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).
This commit is contained in:
parent
8682d12adb
commit
ca2b8ac385
5 changed files with 196 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
91
mk/check/check-relro-elf.awk
Normal file
91
mk/check/check-relro-elf.awk
Normal file
|
@ -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); }
|
89
mk/check/check-relro.mk
Normal file
89
mk/check/check-relro.mk
Normal file
|
@ -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
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue