summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpho <pho@pkgsrc.org>2022-01-18 01:41:09 +0000
committerpho <pho@pkgsrc.org>2022-01-18 01:41:09 +0000
commit91f2287d949f2b35f47e42bef8598319147d2018 (patch)
treea3d293f54f054a3b5a581a5be7e73a344a37cf5b
parentea450378fdad98949c8c4099cad6e9ebf5288666 (diff)
downloadpkgsrc-91f2287d949f2b35f47e42bef8598319147d2018.tar.gz
Add a package-settable variable PKGSRC_OVERRIDE_MKPIE
This is needed by packages that require hand-holding in building PIE. Also a post-build check for MKPIE is performed by default when PKG_DEVELOPER=YES.
-rw-r--r--mk/bsd.prefs.mk18
-rw-r--r--mk/check/bsd.check-vars.mk3
-rw-r--r--mk/check/bsd.check.mk3
-rw-r--r--mk/check/check-pie-elf.awk87
-rw-r--r--mk/check/check-pie.mk75
-rw-r--r--mk/compiler/gcc.mk4
-rw-r--r--mk/cwrappers.mk8
-rw-r--r--mk/wrapper/bsd.wrapper.mk4
8 files changed, 191 insertions, 11 deletions
diff --git a/mk/bsd.prefs.mk b/mk/bsd.prefs.mk
index f5a0a7cb15f..eaf4dff2b63 100644
--- a/mk/bsd.prefs.mk
+++ b/mk/bsd.prefs.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.prefs.mk,v 1.415 2021/11/30 09:39:11 jperkin Exp $
+# $NetBSD: bsd.prefs.mk,v 1.416 2022/01/18 01:41:09 pho Exp $
#
# This file includes the mk.conf file, which contains the user settings.
#
@@ -27,6 +27,17 @@
# directory. Typical values look like editors/emacs or
# misc/openoffice-bin.
#
+# Package-settable variables:
+#
+# PKGSRC_OVERRIDE_MKPIE
+# When this variable is set to no, MKPIE is enforced by putting toolchain
+# flags into tool wrapper scripts. Setting it to yes prevents that and
+# shifts the responsibility of building PIE from the pkgsrc infrastructure
+# to an individual package.
+#
+# Possible values: yes, no
+# Default value: no
+#
# Keywords: mk.conf user platform
#
@@ -736,11 +747,12 @@ _BUILD_DEFS+= INIT_SYSTEM
# Allows the security mitigation of ASLR to be used.
# Impact: very small performance drop.
#
-_PKGSRC_MKPIE= no
+PKGSRC_OVERRIDE_MKPIE?= no
+_PKGSRC_MKPIE= no
.if ${PKGSRC_MKPIE:tl} == "yes" && \
${MKPIE_SUPPORTED:Uyes:tl} == "yes" && \
${_OPSYS_SUPPORTS_MKPIE:Uno} == "yes"
-_PKGSRC_MKPIE= yes
+_PKGSRC_MKPIE= yes
.endif
# Enable reproducible build flags
diff --git a/mk/check/bsd.check-vars.mk b/mk/check/bsd.check-vars.mk
index 52c9a6e5b3d..313ec76ea21 100644
--- a/mk/check/bsd.check-vars.mk
+++ b/mk/check/bsd.check-vars.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.check-vars.mk,v 1.10 2017/10/03 09:43:06 jperkin Exp $
+# $NetBSD: bsd.check-vars.mk,v 1.11 2022/01/18 01:41:09 pho Exp $
#
# This Makefile fragment is included separately by bsd.pkg.mk and
# defines some variables which must be defined earlier than where
@@ -6,6 +6,7 @@
#
CHECK_FILES_SUPPORTED?= yes
+CHECK_PIE_SUPPORTED?= yes
CHECK_RELRO_SUPPORTED?= yes
CHECK_SHLIBS_SUPPORTED?= yes
CHECK_SSP_SUPPORTED?= yes
diff --git a/mk/check/bsd.check.mk b/mk/check/bsd.check.mk
index 0a698c47ac9..53f40f7348d 100644
--- a/mk/check/bsd.check.mk
+++ b/mk/check/bsd.check.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.check.mk,v 1.10 2017/10/03 09:43:06 jperkin Exp $
+# $NetBSD: bsd.check.mk,v 1.11 2022/01/18 01:41:09 pho Exp $
#
# This Makefile fragment is included by bsd.pkg.mk and provides all
# variables and targets related to build and install checks.
@@ -29,6 +29,7 @@
.include "check-headers.mk"
.include "check-interpreter.mk"
.include "check-perms.mk"
+.include "check-pie.mk"
.include "check-portability.mk"
.include "check-relro.mk"
.include "check-shlibs.mk"
diff --git a/mk/check/check-pie-elf.awk b/mk/check/check-pie-elf.awk
new file mode 100644
index 00000000000..5dd15bf8b24
--- /dev/null
+++ b/mk/check/check-pie-elf.awk
@@ -0,0 +1,87 @@
+# $NetBSD: check-pie-elf.awk,v 1.1 2022/01/18 01:41:09 pho Exp $
+#
+# Read a list of potential ELF binaries from stdin. For each, extract the list
+# of headers. There are four possibilities:
+#
+# 1. Elf_Ehdr.e_type == ET_EXEC &&
+# PT_INTERP does not exist
+#
+# This is a statically-linked executable. Ignore these, as they cannot
+# ever be a PIE.
+#
+# 2. Elf_Ehdr.e_type == ET_EXEC &&
+# PT_INTERP exists in the program headers
+#
+# This is a dynamically-linked non-PIE that this script complains about.
+#
+# 3. Elf_Ehdr.e_type == ET_DYN &&
+# PT_INTERP exists in the program headers &&
+# DT_FLAGS_1 exists in the dynamic section &&
+# DT_FLAGS_1 contains DF_1_PIE
+#
+# This is a PIE.
+#
+# 4. Elf_Ehdr.e_type == ET_DYN &&
+# PT_INTERP does not exist in the program headers
+#
+# This is a shared object.
+#
+# See also https://stackoverflow.com/a/55704865
+#
+
+function shquote(IN, out) {
+ out = IN;
+ gsub("\\\\", "\\\\", out);
+ gsub("\\\n", "\\n", out);
+ gsub("\\\t", "\\t", out);
+ gsub(" ", "\\ ", out);
+ gsub("'", "\\'", out);
+ gsub("`", "\\`", out);
+ gsub("\"", "\\\"", out);
+ gsub(";", "\\;", out);
+ gsub("&", "\\&", out);
+ gsub("<", "\\<", out);
+ gsub(">", "\\>", out);
+ gsub("\\(", "\\(", out);
+ gsub("\\)", "\\)", out);
+ gsub("\\|", "\\|", out);
+ gsub("\\*", "\\*", out);
+ gsub("\\?", "\\?", out);
+ gsub("\\{", "\\{", out);
+ gsub("\\}", "\\}", out);
+ gsub("\\[", "\\[", out);
+ gsub("\\]", "\\]", out);
+ gsub("\\$", "\\$", out);
+ gsub("!", "\\!", out);
+ gsub("#", "\\#", out);
+ gsub("\\^", "\\^", out);
+ gsub("~", "\\~", out);
+ return out;
+}
+
+function check_pie(ELF, is_non_pie, is_dyn_exec) {
+ is_non_pie = 0;
+ is_dyn_exec = 0;
+ cmd = readelf " -Whl " shquote(ELF) " 2>/dev/null";
+ while ((cmd | getline) > 0) {
+ if ($1 == "Type:" && $2 == "EXEC") {
+ is_non_pie = 1;
+ }
+ else if ($1 == "INTERP") {
+ is_dyn_exec = 1;
+ }
+ }
+ close(cmd);
+ if (is_non_pie == 1 && is_dyn_exec == 1) {
+ print ELF ": not a PIE";
+ }
+}
+
+BEGIN {
+ readelf = ENVIRON["READELF"];
+ if (readelf == "") {
+ readelf = "readelf";
+ }
+}
+
+{ check_pie($0); }
diff --git a/mk/check/check-pie.mk b/mk/check/check-pie.mk
new file mode 100644
index 00000000000..8d309ca68a2
--- /dev/null
+++ b/mk/check/check-pie.mk
@@ -0,0 +1,75 @@
+# $NetBSD
+#
+# This file verifies that MKPIE (position-independent executables) was applied
+# accordingly at build-time.
+#
+# User-settable variables:
+#
+# CHECK_PIE
+# Whether the check should be enabled or not.
+#
+# Default value: "yes" for PKG_DEVELOPERs, "no" otherwise.
+#
+# Package-settable variables:
+#
+# CHECK_PIE_SKIP
+# A list of shell patterns (like man/*) that should be excluded
+# from the check. Note that a * in a pattern also matches a slash
+# in a pathname.
+#
+# Default value: empty.
+#
+# CHECK_PIE_SUPPORTED
+# Whether the check should be enabled for this package or not.
+#
+# Default value: yes
+#
+
+_VARGROUPS+= check-pie
+_USER_VARS.check-pie= CHECK_PIE
+_PKG_VARS.check-pie= CHECK_PIE_SUPPORTED
+
+.if ${_PKGSRC_MKPIE:Uno} != "no" && ${PKG_DEVELOPER:Uno:tl} != "no"
+CHECK_PIE?= yes
+.else
+CHECK_PIE?= no
+.endif
+CHECK_PIE_SUPPORTED?= yes
+CHECK_PIE_SKIP?= # none
+
+# All binaries but not libraries
+_CHECK_PIE_ERE= (bin/|sbin/|libexec/)
+
+_CHECK_PIE_FILELIST_CMD?= \
+ ${SED} -e '/^@/d' ${PLIST} | \
+ while read file; do \
+ ${TEST} -h "$$file" || ${ECHO} "$$file"; \
+ done
+
+_CHECK_PIE_CMD= # empty
+.if ${OBJECT_FMT} == "ELF"
+USE_TOOLS+= awk readelf
+_CHECK_PIE_CMD= ${AWK} -f ${PKGSRCDIR}/mk/check/check-pie-elf.awk
+_CHECK_PIE_ENV+= READELF=${TOOLS_PATH.readelf:Q}
+.endif
+
+.if ${CHECK_PIE:tl} == "yes" && \
+ ${CHECK_PIE_SUPPORTED:tl} == "yes" && \
+ !empty(_CHECK_PIE_CMD)
+privileged-install-hook: _check-pie
+_check-pie: error-check .PHONY
+ @${STEP_MSG} "Checking for PIE in ${PKGNAME}"
+ ${RUN} rm -f ${ERROR_DIR}/${.TARGET}
+ ${RUN} \
+ cd ${DESTDIR:Q}${PREFIX:Q}; \
+ ${_CHECK_PIE_FILELIST_CMD} | \
+ ${EGREP} -h ${_CHECK_PIE_ERE:Q} | \
+ while read file; do \
+ case "$$file" in \
+ ${CHECK_PIE_SKIP:@p@${p}) continue;;@} \
+ *) ${ECHO} "$$file"; \
+ esac; \
+ done | \
+ ${PKGSRC_SETENV} ${_CHECK_PIE_ENV} ${_CHECK_PIE_CMD} \
+ > ${ERROR_DIR}/${.TARGET}
+.endif
diff --git a/mk/compiler/gcc.mk b/mk/compiler/gcc.mk
index 03f40a601e2..0694941749f 100644
--- a/mk/compiler/gcc.mk
+++ b/mk/compiler/gcc.mk
@@ -1,4 +1,4 @@
-# $NetBSD: gcc.mk,v 1.234 2021/12/22 10:14:27 nia Exp $
+# $NetBSD: gcc.mk,v 1.235 2022/01/18 01:41:09 pho Exp $
#
# This is the compiler definition for the GNU Compiler Collection.
#
@@ -352,6 +352,7 @@ _MKPIE_FCFLAGS.gcc= -fPIC
# XXX for libraries a sink wrapper around gcc is required and used instead
_MKPIE_LDFLAGS.gcc= -pie
+. if ${PKGSRC_OVERRIDE_MKPIE:tl} == "no"
_GCC_CFLAGS+= ${_MKPIE_CFLAGS.gcc}
_GCC_FCFLAGS+= ${_MKPIE_FCFLAGS.gcc}
#_GCC_LDFLAGS+= ${_MKPIE_LDFLAGS.gcc}
@@ -360,6 +361,7 @@ CWRAPPERS_APPEND.cxx+= ${_MKPIE_CFLAGS.gcc}
CWRAPPERS_APPEND.f77+= ${_MKPIE_FCFLAGS.gcc}
# this differs for libraries and executables (handled in mk/cwrappers.mk)
# CWRAPPERS_APPEND.ld+= ${_MKPIE_LDFLAGS.gcc}
+. endif
.endif
.if ${_PKGSRC_MKREPRO} == "yes"
diff --git a/mk/cwrappers.mk b/mk/cwrappers.mk
index ede824686a7..1a9a2461fcf 100644
--- a/mk/cwrappers.mk
+++ b/mk/cwrappers.mk
@@ -1,4 +1,4 @@
-# $NetBSD: cwrappers.mk,v 1.31 2019/05/07 19:36:43 rillig Exp $
+# $NetBSD: cwrappers.mk,v 1.32 2022/01/18 01:41:09 pho Exp $
#
# This Makefile fragment implements integration of pkgtools/cwrappers.
@@ -89,9 +89,11 @@ generate-cwrappers:
${RUN}ln -s ${CWRAPPERS_SRC_DIR}/${CWRAPPERS_CONFIG.${wrappee}}-wrapper ${WRAPPER_BINDIR}/${alias}
. endfor
. if ${_PKGSRC_MKPIE} == "yes"
-. for arg in ${_MKPIE_LDFLAGS.gcc}
+. if ${PKGSRC_OVERRIDE_MKPIE:tl} == "no"
+. for arg in ${_MKPIE_LDFLAGS.gcc}
${RUN}echo append_executable=${arg} >> ${CWRAPPERS_CONFIG_DIR}/${CWRAPPERS_CONFIG.${wrappee}}
-. endfor
+. endfor
+. endif
. endif
.endfor
diff --git a/mk/wrapper/bsd.wrapper.mk b/mk/wrapper/bsd.wrapper.mk
index 0a3241ec42f..ac36e94b97b 100644
--- a/mk/wrapper/bsd.wrapper.mk
+++ b/mk/wrapper/bsd.wrapper.mk
@@ -1,4 +1,4 @@
-# $NetBSD: bsd.wrapper.mk,v 1.102 2020/04/27 05:23:11 rillig Exp $
+# $NetBSD: bsd.wrapper.mk,v 1.103 2022/01/18 01:41:09 pho Exp $
#
# Copyright (c) 2005 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -304,7 +304,7 @@ _WRAP_TRANSFORM.CXX= ${_WRAP_TRANSFORM.CC}
.if !empty(PKGSRC_COMPILER:Mgcc)
_WRAP_TRANSFORM.CC= ${WRAPPER_TMPDIR}/transform-gcc
_WRAP_TRANSFORM.CXX= ${_WRAP_TRANSFORM.CC}
-. if ${_PKGSRC_MKPIE} != "no"
+. if ${_PKGSRC_MKPIE} != "no" && ${PKGSRC_OVERRIDE_MKPIE:tl} == "no"
_WRAP_CMD_SINK.CC= ${WRAPPER_TMPDIR}/cmd-sink-mkpie-gcc
_WRAP_CMD_SINK.CXX= ${_WRAP_CMD_SINK.CC}
_WRAP_CMD_SINK.LD= ${WRAPPER_TMPDIR}/cmd-sink-mkpie-ld