tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Checking for RELRO with PKG_DEVELOPER=yes



			Hi tech-pkg@,

from the feedback I received directly during my talk at BSDCan, "Hardening pkgsrc" [1] (thanks for the idea!) I have implemented a check for RELRO with PKG_DEVELOPER set [2]. The corresponding patch is attached.

I will greatly appreciate review, since:
- it is based on the check for shlibs from joerg@
  * consistency?
  * any code factoring in sight?
  * is the attribution correct?
- also, it is my first program in awk :)

Or let me know if it is good enough to commit already. It does not change anything to the current operation by the way, unless PKGSRC_USE_RELRO is changed from the default "no".

Also note that it doubles as a check for the packages to effectively be respecting LDFLAGS.

[1] http://www.bsdcan.org/2017/schedule/events/818.en.html
[2] https://git.edgebsd.org/gitweb/?p=pkgsrc.git;a=commitdiff;h=4c4cfc7d000036b7bd2535898a4fe037d4b7cb5e

Cheers!
--
khorben
From: Pierre Pronchery <khorben%EdgeBSD.org@localhost>
Date: Wed, 14 Jun 2017 04:53:21 +0000 (-0400)
Subject: Implement a check for RELRO
X-Git-Url: https://git.edgebsd.org/gitweb/?p=pkgsrc.git;a=commitdiff_plain;h=4c4cfc7d000036b7bd2535898a4fe037d4b7cb5e

Implement a check for RELRO
---

diff --git a/mk/check/bsd.check-vars.mk b/mk/check/bsd.check-vars.mk
index d7cc59e..c24925d 100644
--- a/mk/check/bsd.check-vars.mk
+++ b/mk/check/bsd.check-vars.mk
@@ -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 8db4197..5bc6c33 100644
--- a/mk/check/bsd.check.mk
+++ b/mk/check/bsd.check.mk
@@ -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 0000000..1883648
--- /dev/null
+++ b/mk/check/check-relro-elf.awk
@@ -0,0 +1,91 @@
+# $NetBSD$
+#
+# Copyright (c) 2007 Joerg Sonnenberger <joerg%NetBSD.org@localhost>.
+# Copyright (c) 2017 Pierre Pronchery <khorben%NetBSD.org@localhost>.
+# 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 0000000..d988bcf
--- /dev/null
+++ b/mk/check/check-relro.mk
@@ -0,0 +1,89 @@
+# $NetBSD$
+#
+# 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 42434a7..35f560f 100644
--- a/mk/platform/NetBSD.mk
+++ b/mk/platform/NetBSD.mk
@@ -145,7 +145,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.


Home | Main Index | Thread Index | Old Index