diff options
author | pho <pho@pkgsrc.org> | 2022-01-18 01:41:09 +0000 |
---|---|---|
committer | pho <pho@pkgsrc.org> | 2022-01-18 01:41:09 +0000 |
commit | 91f2287d949f2b35f47e42bef8598319147d2018 (patch) | |
tree | a3d293f54f054a3b5a581a5be7e73a344a37cf5b | |
parent | ea450378fdad98949c8c4099cad6e9ebf5288666 (diff) | |
download | pkgsrc-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.mk | 18 | ||||
-rw-r--r-- | mk/check/bsd.check-vars.mk | 3 | ||||
-rw-r--r-- | mk/check/bsd.check.mk | 3 | ||||
-rw-r--r-- | mk/check/check-pie-elf.awk | 87 | ||||
-rw-r--r-- | mk/check/check-pie.mk | 75 | ||||
-rw-r--r-- | mk/compiler/gcc.mk | 4 | ||||
-rw-r--r-- | mk/cwrappers.mk | 8 | ||||
-rw-r--r-- | mk/wrapper/bsd.wrapper.mk | 4 |
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 |