diff options
author | khorben <khorben@pkgsrc.org> | 2017-07-04 18:29:24 +0000 |
---|---|---|
committer | khorben <khorben@pkgsrc.org> | 2017-07-04 18:29:24 +0000 |
commit | e504de32d6dadead694949e633f537a84f02ef62 (patch) | |
tree | cc1a8a45554fd94c2cae87753a6c3c0ba19bf994 | |
parent | f9c7bc7d0cd2a028ed68aa615536d06954995cc8 (diff) | |
download | pkgsrc-e504de32d6dadead694949e633f537a84f02ef62.tar.gz |
Implement a check for RELRO
This is only performed if PKG_DEVELOPER and RELRO are in use.
After a suggestion during my talk at BSDCan 2017; thanks!
Also, submitted on tech-pkg@ for review mid-June.
As a next step, it seems this can be extended to libraries, just like the
check for SHLIBS does (from which this is inspired).
-rw-r--r-- | mk/check/bsd.check-vars.mk | 11 | ||||
-rw-r--r-- | mk/check/bsd.check.mk | 3 | ||||
-rw-r--r-- | mk/check/check-relro-elf.awk | 91 | ||||
-rw-r--r-- | mk/check/check-relro.mk | 89 | ||||
-rw-r--r-- | mk/platform/NetBSD.mk | 6 |
5 files changed, 196 insertions, 4 deletions
diff --git a/mk/check/bsd.check-vars.mk b/mk/check/bsd.check-vars.mk index d7cc59e24fe..053c51adcfd 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.8 2015/08/17 17:35:23 jperkin Exp $ +# $NetBSD: bsd.check-vars.mk,v 1.9 2017/07/04 18:29:24 khorben Exp $ # # This Makefile fragment is included separately by bsd.pkg.mk and # defines some variables which must be defined earlier than where @@ -6,8 +6,17 @@ # CHECK_FILES_SUPPORTED?= yes +CHECK_RELRO_SUPPORTED?= yes CHECK_SHLIBS_SUPPORTED?= yes +_OPSYS_CAN_CHECK_RELRO?= ${_OPSYS_CAN_CHECK_SHLIBS} + +.if ${_OPSYS_CAN_CHECK_RELRO:tl} == "yes" +_USE_CHECK_RELRO_NATIVE= yes +.else +_USE_CHECK_RELRO_NATIVE= no +.endif + .if ${_OPSYS_CAN_CHECK_SHLIBS:tl} == "yes" _USE_CHECK_SHLIBS_NATIVE= yes .else diff --git a/mk/check/bsd.check.mk b/mk/check/bsd.check.mk index 8db4197e4b1..78eab8d9a22 100644 --- a/mk/check/bsd.check.mk +++ b/mk/check/bsd.check.mk @@ -1,4 +1,4 @@ -# $NetBSD: bsd.check.mk,v 1.8 2008/02/13 15:02:20 rillig Exp $ +# $NetBSD: bsd.check.mk,v 1.9 2017/07/04 18:29:24 khorben Exp $ # # This Makefile fragment is included by bsd.pkg.mk and provides all # variables and targets related to build and install checks. @@ -30,6 +30,7 @@ .include "check-interpreter.mk" .include "check-perms.mk" .include "check-portability.mk" +.include "check-relro.mk" .include "check-shlibs.mk" .include "check-stripped.mk" .include "check-vulnerable.mk" diff --git a/mk/check/check-relro-elf.awk b/mk/check/check-relro-elf.awk new file mode 100644 index 00000000000..3c48ad1b020 --- /dev/null +++ b/mk/check/check-relro-elf.awk @@ -0,0 +1,91 @@ +# $NetBSD: check-relro-elf.awk,v 1.1 2017/07/04 18:29:24 khorben Exp $ +# +# Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. +# Copyright (c) 2017 Pierre Pronchery <khorben@NetBSD.org>. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Joerg Sonnenberger. +# +# Originally developed as part of Google's Summer of Code 2007 program. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# +# Read a list of potential ELF binaries from stdin. +# For each, extract the list of program headers. +# Check that the GNU_RELRO header is present. +# + +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 checkrelro(ELF, got_relro) { + cmd = readelf " -Wl " shquote(ELF) " 2> /dev/null" + while ((cmd | getline) > 0) { + if ($1 == "GNU_RELRO") { + got_relro = 1 + } + } + close(cmd) + if (got_relro != 1) { + print ELF ": missing RELRO" + } +} + +BEGIN { + readelf = ENVIRON["READELF"] + if (readelf == "") + readelf = "readelf" +} + +{ checkrelro($0); } diff --git a/mk/check/check-relro.mk b/mk/check/check-relro.mk new file mode 100644 index 00000000000..cc897de6c0a --- /dev/null +++ b/mk/check/check-relro.mk @@ -0,0 +1,89 @@ +# $NetBSD: check-relro.mk,v 1.1 2017/07/04 18:29:24 khorben Exp $ +# +# This file verifies that RELRO was applied accordingly at build-time. +# +# User-settable variables: +# +# CHECK_RELRO +# Whether the check should be enabled or not. +# +# Default value: "yes" for PKG_DEVELOPERs, "no" otherwise. +# +# Package-settable variables: +# +# CHECK_RELRO_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_RELRO_SUPPORTED +# Whether the check should be enabled for this package or not. +# +# Default value: yes +# + +_VARGROUPS+= check-relro +_USER_VARS.check-relro= CHECK_RELRO +_PKG_VARS.check-relro= CHECK_RELRO_SUPPORTED + +.if ${PKGSRC_USE_RELRO:Uno} != "no" && \ + ${PKG_DEVELOPER:Uno} != "no" +CHECK_RELRO?= yes +.else +CHECK_RELRO?= no +.endif +CHECK_RELRO_SUPPORTED?= yes +CHECK_RELRO_SKIP?= # none + +# All binaries. +_CHECK_RELRO_ERE= (bin/|sbin/|libexec/) + +_CHECK_RELRO_FILELIST_CMD?= ${SED} -e '/^@/d' ${PLIST} | \ + (while read file; do \ + ${TEST} -h "$$file" || ${ECHO} "$$file"; \ + done) + +.if !empty(CHECK_RELRO:M[Yy][Ee][Ss]) && \ + !empty(CHECK_RELRO_SUPPORTED:M[Yy][Ee][Ss]) +privileged-install-hook: _check-relro +.endif + +.if ${_USE_CHECK_RELRO_NATIVE} == "yes" +CHECK_RELRO_NATIVE_ENV= +. if ${OBJECT_FMT} == "ELF" +USE_TOOLS+= readelf +CHECK_RELRO_NATIVE= ${PKGSRCDIR}/mk/check/check-relro-elf.awk +CHECK_RELRO_NATIVE_ENV+= PLATFORM_RPATH=${_OPSYS_SYSTEM_RPATH:Q} +CHECK_RELRO_NATIVE_ENV+= READELF=${TOOLS_PATH.readelf:Q} +. endif +CHECK_RELRO_NATIVE_ENV+= CROSS_DESTDIR=${_CROSS_DESTDIR:Q} +CHECK_RELRO_NATIVE_ENV+= PKG_INFO_CMD=${PKG_INFO:Q} +CHECK_RELRO_NATIVE_ENV+= DEPENDS_FILE=${_RRDEPENDS_FILE:Q} +CHECK_RELRO_NATIVE_ENV+= DESTDIR=${DESTDIR:Q} +CHECK_RELRO_NATIVE_ENV+= WRKDIR=${WRKDIR:Q} +. if defined(CHECK_WRKREF) && !empty(CHECK_WRKREF:Mextra) +CHECK_RELRO_NATIVE_ENV+= CHECK_WRKREF_EXTRA_DIRS=${CHECK_WRKREF_EXTRA_DIRS:Q} +. endif + +_check-relro: error-check .PHONY + @${STEP_MSG} "Checking for RELRO in ${PKGNAME}" + ${RUN} rm -f ${ERROR_DIR}/${.TARGET} + ${RUN} \ + cd ${DESTDIR:Q}${PREFIX:Q}; \ + ${_CHECK_RELRO_FILELIST_CMD} | \ + ${EGREP} -h ${_CHECK_RELRO_ERE:Q} | \ + while read file; do \ + case "$$file" in \ + ${CHECK_RELRO_SKIP:@p@${p}) continue ;;@} \ + *) ;; \ + esac; \ + ${ECHO} $$file; \ + done | \ + ${PKGSRC_SETENV} ${CHECK_RELRO_NATIVE_ENV} ${AWK} -f ${CHECK_RELRO_NATIVE} > ${ERROR_DIR}/${.TARGET} + +.else +_check-relro: error-check .PHONY + @${WARNING_MSG} "Skipping check for RELRO in DESTDIR mode." +.endif diff --git a/mk/platform/NetBSD.mk b/mk/platform/NetBSD.mk index 63aca1ff295..ffac5ec5e8a 100644 --- a/mk/platform/NetBSD.mk +++ b/mk/platform/NetBSD.mk @@ -1,4 +1,4 @@ -# $NetBSD: NetBSD.mk,v 1.50 2017/05/31 22:55:01 jlam Exp $ +# $NetBSD: NetBSD.mk,v 1.51 2017/07/04 18:29:24 khorben Exp $ # # Variable definitions for the NetBSD operating system. @@ -156,7 +156,9 @@ _OPSYS_SUPPORTS_SSP= yes _OPSYS_SUPPORTS_CWRAPPERS= yes -_OPSYS_CAN_CHECK_SHLIBS= yes # use readelf in check/bsd.check-vars.mk +# use readelf in check/bsd.check-vars.mk +_OPSYS_CAN_CHECK_RELRO= yes +_OPSYS_CAN_CHECK_SHLIBS= yes # check for maximum command line length and set it in configure's environment, # to avoid a test required by the libtool script that takes forever. |