Blame SOURCES/003-harden-toolchain.patch

fada68
From 658fff9445711b8402029bc2916fccbc5d6fd8fc Mon Sep 17 00:00:00 2001
fada68
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
fada68
Date: Tue, 21 Jun 2016 19:16:43 +0200
fada68
Subject: [PATCH 1/2] Feature: conditional hardening, especially for daemons +
fada68
 libraries
fada68
fada68
So far the build system has not been concerned with run-time hardening
fada68
measures the typical toolchains provide (beside unconditional enforcing
fada68
of -fstack-protector-all).  Hence make a step in that direction,
fada68
enabling following if available and anticipating more to come:
fada68
fada68
[$LD -z relro]
fada68
- daemons incl. libs
fada68
- make some parts of Global Offset Table (GOT) read-only
fada68
fada68
[$CC -fPIE + ld -pie]
fada68
- daemons
fada68
- benefit from Address Space Layout Randomization (ASLR) for code
fada68
  areas
fada68
fada68
[$LD -z now]
fada68
- daemons incl. libs, only when the former two features are supported
fada68
- all symbols are resolved initially to that complete GOT is read-only
fada68
fada68
[$CC -fstack-protector-strong/-fstack-protector-all/-fstack-protector]
fada68
- universal
fada68
- extra run-time checks for buffer overflows
fada68
- NOTE:
fada68
  in case -fstack-protector-strong is supported, this is effectively
fada68
  a weakening of previously enforced -fstack-protector-all, but note
fada68
  that this variant comes with not entirely negligible performance
fada68
  penalty [1], making "strong" variant a reasonable tradeoff for
fada68
  something that is not in the prime line of possible attacks
fada68
fada68
For details on how to instruct configure script to do the right
fada68
thing (for when the default won't cut it), see detailed comment
fada68
in configure.ac under "Hardening flags" section.
fada68
fada68
[1] http://nvlpubs.nist.gov/nistpubs/TechnicalNotes/NIST.TN.1860.pdf
fada68
---
fada68
 acinclude.m4               |  25 +++++++++
fada68
 attrd/Makefile.am          |   3 +
fada68
 cib/Makefile.am            |   3 +
fada68
 configure.ac               | 135 +++++++++++++++++++++++++++++++++++++++++++--
fada68
 crmd/Makefile.am           |   3 +
fada68
 fencing/Makefile.am        |   3 +
fada68
 lib/cib/Makefile.am        |   3 +
fada68
 lib/cluster/Makefile.am    |   4 ++
fada68
 lib/common/Makefile.am     |   4 ++
fada68
 lib/fencing/Makefile.am    |   4 ++
fada68
 lib/lrmd/Makefile.am       |   4 ++
fada68
 lib/pengine/Makefile.am    |   8 +++
fada68
 lib/services/Makefile.am   |   3 +
fada68
 lib/transition/Makefile.am |   3 +
fada68
 lrmd/Makefile.am           |   6 ++
fada68
 mcp/Makefile.am            |   3 +
fada68
 pacemaker.spec.in          |  17 ++++++
fada68
 pengine/Makefile.am        |   6 ++
fada68
 18 files changed, 231 insertions(+), 6 deletions(-)
fada68
 create mode 100644 acinclude.m4
fada68
fada68
diff --git a/acinclude.m4 b/acinclude.m4
fada68
new file mode 100644
fada68
index 0000000..ecaa1dd
fada68
--- /dev/null
fada68
+++ b/acinclude.m4
fada68
@@ -0,0 +1,25 @@
fada68
+dnl
fada68
+dnl local autoconf/automake macros for pacemaker
fada68
+dnl
fada68
+
fada68
+dnl Check if the flag is supported by linker (cacheable)
fada68
+dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
fada68
+dnl
fada68
+dnl Origin (declared license: GPLv2+ with less restrictive exception):
fada68
+dnl https://git.gnome.org/browse/glib/tree/m4macros/attributes.m4?h=2.49.1
fada68
+dnl (AC_LANG_PROGRAM substituted by Jan Pokorny <jpokorny@redhat.com>)
fada68
+
fada68
+AC_DEFUN([CC_CHECK_LDFLAGS], [
fada68
+  AC_CACHE_CHECK([if $CC supports $1 flag],
fada68
+    AS_TR_SH([cc_cv_ldflags_$1]),
fada68
+    [ac_save_LDFLAGS="$LDFLAGS"
fada68
+     LDFLAGS="$LDFLAGS $1"
fada68
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
fada68
+       [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
fada68
+       [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
fada68
+     LDFLAGS="$ac_save_LDFLAGS"
fada68
+    ])
fada68
+
fada68
+  AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
fada68
+    [$2], [$3])
fada68
+])
fada68
diff --git a/attrd/Makefile.am b/attrd/Makefile.am
fada68
index a116e0e..6eaaae2 100644
fada68
--- a/attrd/Makefile.am
fada68
+++ b/attrd/Makefile.am
fada68
@@ -21,6 +21,9 @@ halibdir	= $(CRM_DAEMON_DIR)
fada68
 halib_PROGRAMS	= attrd
fada68
 ## SOURCES
fada68
 
fada68
+attrd_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+attrd_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 attrd_LDADD	= $(top_builddir)/lib/cluster/libcrmcluster.la	\
fada68
 		$(top_builddir)/lib/common/libcrmcommon.la	\
fada68
 		$(top_builddir)/lib/cib/libcib.la		\
fada68
diff --git a/cib/Makefile.am b/cib/Makefile.am
fada68
index fcb8ce9..4273191 100644
fada68
--- a/cib/Makefile.am
fada68
+++ b/cib/Makefile.am
fada68
@@ -32,6 +32,9 @@ halib_PROGRAMS	= cib cibmon
fada68
 ## SOURCES
fada68
 noinst_HEADERS	= callbacks.h cibio.h cibmessages.h common.h notify.h
fada68
 
fada68
+cib_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+cib_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 cib_LDADD	= $(top_builddir)/lib/cluster/libcrmcluster.la \
fada68
 		$(COMMONLIBS) $(CRYPTOLIB) $(CLUSTERLIBS)
fada68
 
fada68
diff --git a/configure.ac b/configure.ac
fada68
index c5b30dc..edf6a91 100644
fada68
--- a/configure.ac
fada68
+++ b/configure.ac
fada68
@@ -196,6 +196,13 @@ AC_ARG_ENABLE([systemd],
fada68
     [  --enable-systemd
fada68
        Do not build support for the Systemd init system [default=yes]])
fada68
 
fada68
+AC_ARG_ENABLE(hardening,
fada68
+    [  --with-hardening
fada68
+       Harden the resulting executables/libraries (best effort by default)],
fada68
+    [ HARDENING="${enableval}" ],
fada68
+    [ HARDENING=try ],
fada68
+)
fada68
+
fada68
 AC_ARG_WITH(ais,
fada68
     [  --with-ais
fada68
        Support the Corosync messaging and membership layer ],
fada68
@@ -1710,6 +1717,12 @@ if export | fgrep " CFLAGS=" > /dev/null; then
fada68
 	unset SAVED_CFLAGS
fada68
 fi
fada68
 
fada68
+AC_ARG_VAR([CFLAGS_HARDENED_LIB], [extra C compiler flags for hardened libraries])
fada68
+AC_ARG_VAR([LDFLAGS_HARDENED_LIB], [extra linker flags for hardened libraries])
fada68
+
fada68
+AC_ARG_VAR([CFLAGS_HARDENED_EXE], [extra C compiler flags for hardened executables])
fada68
+AC_ARG_VAR([LDFLAGS_HARDENED_EXE], [extra linker flags for hardened executables])
fada68
+
fada68
 CC_EXTRAS=""
fada68
 
fada68
 if test "$GCC" != yes; then
fada68
@@ -1785,12 +1798,6 @@ dnl otherwise none of both
fada68
 # Additional warnings it might be nice to enable one day
fada68
 #		-Wshadow
fada68
 #		-Wunreachable-code
fada68
-	case "$host_os" in
fada68
-	    *solaris*) ;;
fada68
-	    *) EXTRA_FLAGS="$EXTRA_FLAGS
fada68
-			-fstack-protector-all"
fada68
-		;;
fada68
-	esac
fada68
 	for j in $EXTRA_FLAGS
fada68
 	do
fada68
 	  if
fada68
@@ -1829,6 +1836,118 @@ dnl System specific options
fada68
   	AC_MSG_NOTICE(Activated additional gcc flags: ${CC_EXTRAS})
fada68
 fi
fada68
 
fada68
+dnl
fada68
+dnl Hardening flags
fada68
+dnl
fada68
+dnl The prime control of whether to apply (targeted) hardening build flags and
fada68
+dnl which ones is --{enable,disable}-hardening option passed to ./configure:
fada68
+dnl
fada68
+dnl --enable-hardening=try (default):
fada68
+dnl     depending on whether any of CFLAGS_HARDENED_EXE, LDFLAGS_HARDENED_EXE,
fada68
+dnl     CFLAGS_HARDENED_LIB or LDFLAGS_HARDENED_LIB environment variables
fada68
+dnl     (see below) is set and non-null, all these custom flags (even if not
fada68
+dnl     set) are used as are, otherwise the best effort is made to offer
fada68
+dnl     reasonably strong hardening in several categories (RELRO, PIE,
fada68
+dnl     "bind now", stack protector) according to what the selected toolchain
fada68
+dnl     can offer
fada68
+dnl
fada68
+dnl --enable-hardening:
fada68
+dnl     same effect as --enable-hardening=try when the environment variables
fada68
+dnl     in question are suppressed
fada68
+dnl
fada68
+dnl --disable-hardening:
fada68
+dnl     do not apply any targeted hardening measures at all
fada68
+dnl
fada68
+dnl The user-injected environment variables that regulate the hardening in
fada68
+dnl default case are as follows:
fada68
+dnl
fada68
+dnl * CFLAGS_HARDENED_EXE, LDFLAGS_HARDENED_EXE
fada68
+dnl    compiler and linker flags (respectively) for daemon programs
fada68
+dnl    (attrd, cib, crmd, lrmd, stonithd, pacemakerd, pacemaker_remoted,
fada68
+dnl    pengine)
fada68
+dnl
fada68
+dnl * CFLAGS_HARDENED_LIB, LDFLAGS_HARDENED_LIB
fada68
+dnl    compiler and linker flags (respectively) for libraries linked
fada68
+dnl    with the daemon programs
fada68
+dnl
fada68
+dnl Note that these are purposedly targeted variables (addressing particular
fada68
+dnl targets all over the scattered Makefiles) and have no effect outside of
fada68
+dnl the predestined scope (e.g., CLI utilities).  For a global reach,
fada68
+dnl use CFLAGS, LDFLAGS, etc. as usual.
fada68
+dnl
fada68
+dnl For guidance on the suitable flags consult, for instance:
fada68
+dnl https://fedoraproject.org/wiki/Changes/Harden_All_Packages#Detailed_Harden_Flags_Description
fada68
+dnl https://owasp.org/index.php/C-Based_Toolchain_Hardening#GCC.2FBinutils
fada68
+dnl
fada68
+
fada68
+if test "x${HARDENING}" != "xtry"; then
fada68
+	unset CFLAGS_HARDENED_EXE
fada68
+	unset CFLAGS_HARDENED_LIB
fada68
+	unset LDFLAGS_HARDENED_EXE
fada68
+	unset LDFLAGS_HARDENED_LIB
fada68
+fi
fada68
+if test "x${HARDENING}" = "xno"; then
fada68
+	AC_MSG_NOTICE([Hardening: explicitly disabled])
fada68
+elif test "x${HARDENING}" = "xyes" \
fada68
+    || test "$(env | grep -Ec '^(C|LD)FLAGS_HARDENED_(EXE|LIB)=.')" = 0; then
fada68
+	dnl We'll figure out on our own...
fada68
+	CFLAGS_HARDENED_EXE=
fada68
+	CFLAGS_HARDENED_LIB=
fada68
+	LDFLAGS_HARDENED_EXE=
fada68
+	LDFLAGS_HARDENED_LIB=
fada68
+	relro=0
fada68
+	pie=0
fada68
+	bindnow=0
fada68
+	# daemons incl. libs: partial RELRO
fada68
+	flag="-Wl,-z,relro"
fada68
+	CC_CHECK_LDFLAGS(["${flag}"],
fada68
+		[LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}";
fada68
+		 LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}";
fada68
+		 relro=1]
fada68
+	)
fada68
+	# daemons: PIE for both CFLAGS and LDFLAGS
fada68
+	if cc_supports_flag -fPIE; then
fada68
+		flag="-pie"
fada68
+		CC_CHECK_LDFLAGS(["${flag}"],
fada68
+			[CFLAGS_HARDENED_EXE="${CFLAGS_HARDENED_EXE} -fPIE";
fada68
+			 LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}";
fada68
+			 pie=1]
fada68
+		)
fada68
+	fi
fada68
+	# daemons incl. libs: full RELRO if sensible
fada68
+	if test "${relro}" = 1 && test "${pie}" = 1; then
fada68
+		flag="-Wl,-z,now"
fada68
+		CC_CHECK_LDFLAGS(["${flag}"],
fada68
+			[LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}";
fada68
+			 LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}";
fada68
+			 bindnow=1]
fada68
+		)
fada68
+	fi
fada68
+	# universal: prefer strong > all > default stack protector if possible
fada68
+	flag=
fada68
+	if cc_supports_flag -fstack-protector-strong; then
fada68
+		flag="-fstack-protector-strong"
fada68
+	elif cc_supports_flag -fstack-protector-all; then
fada68
+		flag="-fstack-protector-all"
fada68
+	elif cc_supports_flag -fstack-protector; then
fada68
+		flag="-fstack-protector"
fada68
+	fi
fada68
+	if test -n "${flag}"; then
fada68
+		CC_EXTRAS="${CC_EXTRAS} ${flag}"
fada68
+		stackprot=1
fada68
+	fi
fada68
+	if test "${relro}" = 1 \
fada68
+	|| test "${pie}" = 1 \
fada68
+	|| test "${stackprot}" = 1; then
fada68
+		AC_MSG_NOTICE(
fada68
+		[Hardening: relro=${relro} pie=${pie} bindnow=${bindnow} stackprot=${flag}])
fada68
+	else
fada68
+		AC_MSG_WARN([Hardening: no suitable features in the toolchain detected])
fada68
+	fi
fada68
+else
fada68
+	AC_MSG_NOTICE([Hardening: using custom flags])
fada68
+fi
fada68
+
fada68
 CFLAGS="$CFLAGS $CC_EXTRAS"
fada68
 
fada68
 NON_FATAL_CFLAGS="$CFLAGS"
fada68
@@ -1978,5 +2097,9 @@ AC_MSG_RESULT([  HA group name            = ${CRM_DAEMON_GROUP}])
fada68
 AC_MSG_RESULT([  HA user name             = ${CRM_DAEMON_USER}])
fada68
 AC_MSG_RESULT([])
fada68
 AC_MSG_RESULT([  CFLAGS                   = ${CFLAGS}])
fada68
+AC_MSG_RESULT([  CFLAGS_HARDENED_EXE      = ${CFLAGS_HARDENED_EXE}])
fada68
+AC_MSG_RESULT([  CFLAGS_HARDENED_LIB      = ${CFLAGS_HARDENED_LIB}])
fada68
+AC_MSG_RESULT([  LDFLAGS_HARDENED_EXE     = ${LDFLAGS_HARDENED_EXE}])
fada68
+AC_MSG_RESULT([  LDFLAGS_HARDENED_LIB     = ${LDFLAGS_HARDENED_LIB}])
fada68
 AC_MSG_RESULT([  Libraries                = ${LIBS}])
fada68
 AC_MSG_RESULT([  Stack Libraries          = ${CLUSTERLIBS}])
fada68
diff --git a/crmd/Makefile.am b/crmd/Makefile.am
fada68
index 979e266..6d5ee9a 100644
fada68
--- a/crmd/Makefile.am
fada68
+++ b/crmd/Makefile.am
fada68
@@ -28,6 +28,9 @@ noinst_HEADERS	= crmd.h crmd_fsa.h crmd_messages.h fsa_defines.h	\
fada68
 		fsa_matrix.h fsa_proto.h crmd_utils.h crmd_callbacks.h	\
fada68
 		crmd_lrm.h te_callbacks.h tengine.h
fada68
 
fada68
+crmd_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+crmd_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 crmd_LDADD	= $(top_builddir)/lib/fencing/libstonithd.la		\
fada68
 		$(top_builddir)/lib/transition/libtransitioner.la	\
fada68
 		$(top_builddir)/lib/pengine/libpe_rules.la		\
fada68
diff --git a/fencing/Makefile.am b/fencing/Makefile.am
fada68
index 1d591fc..c53ead6 100644
fada68
--- a/fencing/Makefile.am
fada68
+++ b/fencing/Makefile.am
fada68
@@ -52,6 +52,9 @@ stonith_admin_LDADD	= $(top_builddir)/lib/common/libcrmcommon.la	\
fada68
 stonithd_CPPFLAGS	= -I$(top_srcdir)/pengine $(AM_CPPFLAGS)
fada68
 stonithd_YFLAGS		= -d
fada68
 
fada68
+stonithd_CFLAGS		= $(CFLAGS_HARDENED_EXE)
fada68
+stonithd_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 stonithd_LDADD		= $(top_builddir)/lib/common/libcrmcommon.la	\
fada68
 			$(top_builddir)/lib/cluster/libcrmcluster.la	\
fada68
 			$(top_builddir)/lib/fencing/libstonithd.la	\
fada68
diff --git a/lib/cib/Makefile.am b/lib/cib/Makefile.am
fada68
index e414a7f..637ea8c 100644
fada68
--- a/lib/cib/Makefile.am
fada68
+++ b/lib/cib/Makefile.am
fada68
@@ -27,6 +27,9 @@ libcib_la_SOURCES	+= cib_file.c cib_remote.c
fada68
 libcib_la_LDFLAGS	= -version-info 5:1:1
fada68
 libcib_la_CPPFLAGS	= -I$(top_srcdir) $(AM_CPPFLAGS)
fada68
 
fada68
+libcib_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libcib_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libcib_la_LIBADD	= $(CRYPTOLIB) $(top_builddir)/lib/pengine/libpe_rules.la $(top_builddir)/lib/common/libcrmcommon.la
fada68
 
fada68
 clean-generic:
fada68
diff --git a/lib/cluster/Makefile.am b/lib/cluster/Makefile.am
fada68
index 06d7066..9a57bbb 100644
fada68
--- a/lib/cluster/Makefile.am
fada68
+++ b/lib/cluster/Makefile.am
fada68
@@ -21,6 +21,10 @@ include $(top_srcdir)/Makefile.common
fada68
 lib_LTLIBRARIES	= libcrmcluster.la 
fada68
 
fada68
 libcrmcluster_la_LDFLAGS = -version-info 6:0:2
fada68
+
fada68
+libcrmcluster_la_CFLAGS  = $(CFLAGS_HARDENED_LIB)
fada68
+libcrmcluster_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libcrmcluster_la_LIBADD  = $(top_builddir)/lib/common/libcrmcommon.la $(top_builddir)/lib/fencing/libstonithd.la $(CLUSTERLIBS)
fada68
 
fada68
 libcrmcluster_la_SOURCES = election.c cluster.c membership.c
fada68
diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am
fada68
index 7550ec1..0e1ad29 100644
fada68
--- a/lib/common/Makefile.am
fada68
+++ b/lib/common/Makefile.am
fada68
@@ -32,6 +32,10 @@ lib_LTLIBRARIES	= libcrmcommon.la
fada68
 CFLAGS		= $(CFLAGS_COPY:-Wcast-qual=) -fPIC
fada68
 
fada68
 libcrmcommon_la_LDFLAGS	= -version-info 9:0:6
fada68
+
fada68
+libcrmcommon_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libcrmcommon_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libcrmcommon_la_LIBADD	= @LIBADD_DL@ $(GNUTLSLIBS) -lm
fada68
 
fada68
 libcrmcommon_la_SOURCES	= compat.c digest.c ipc.c io.c procfs.c utils.c xml.c \
fada68
diff --git a/lib/fencing/Makefile.am b/lib/fencing/Makefile.am
fada68
index 85ae40a..dc15799 100644
fada68
--- a/lib/fencing/Makefile.am
fada68
+++ b/lib/fencing/Makefile.am
fada68
@@ -21,5 +21,9 @@ include $(top_srcdir)/Makefile.common
fada68
 lib_LTLIBRARIES		= libstonithd.la
fada68
 
fada68
 libstonithd_la_LDFLAGS	= -version-info 4:1:2
fada68
+
fada68
+libstonithd_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libstonithd_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libstonithd_la_LIBADD	= $(top_builddir)/lib/common/libcrmcommon.la
fada68
 libstonithd_la_SOURCES	= st_client.c
fada68
diff --git a/lib/lrmd/Makefile.am b/lib/lrmd/Makefile.am
fada68
index 25f3d55..611675e 100644
fada68
--- a/lib/lrmd/Makefile.am
fada68
+++ b/lib/lrmd/Makefile.am
fada68
@@ -19,6 +19,10 @@ include $(top_srcdir)/Makefile.common
fada68
 lib_LTLIBRARIES		= liblrmd.la
fada68
 
fada68
 liblrmd_la_LDFLAGS	= -version-info 4:0:3
fada68
+
fada68
+liblrmd_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+liblrmd_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 liblrmd_la_LIBADD	= $(top_builddir)/lib/common/libcrmcommon.la	\
fada68
 			$(top_builddir)/lib/services/libcrmservice.la	\
fada68
 			$(top_builddir)/lib/fencing/libstonithd.la
fada68
diff --git a/lib/pengine/Makefile.am b/lib/pengine/Makefile.am
fada68
index de760c3..ad5c5c3 100644
fada68
--- a/lib/pengine/Makefile.am
fada68
+++ b/lib/pengine/Makefile.am
fada68
@@ -24,10 +24,18 @@ lib_LTLIBRARIES		= libpe_rules.la libpe_status.la
fada68
 noinst_HEADERS		= unpack.h variant.h
fada68
 
fada68
 libpe_rules_la_LDFLAGS	= -version-info 2:6:0
fada68
+
fada68
+libpe_rules_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libpe_rules_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libpe_rules_la_LIBADD	= $(top_builddir)/lib/common/libcrmcommon.la
fada68
 libpe_rules_la_SOURCES	= rules.c common.c
fada68
 
fada68
 libpe_status_la_LDFLAGS	= -version-info 11:0:1
fada68
+
fada68
+libpe_status_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libpe_status_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libpe_status_la_LIBADD	= @CURSESLIBS@ $(top_builddir)/lib/common/libcrmcommon.la
fada68
 libpe_status_la_SOURCES	= status.c unpack.c utils.c complex.c native.c \
fada68
 			group.c clone.c rules.c common.c remote.c
fada68
diff --git a/lib/services/Makefile.am b/lib/services/Makefile.am
fada68
index c789fbd..b3208c2 100644
fada68
--- a/lib/services/Makefile.am
fada68
+++ b/lib/services/Makefile.am
fada68
@@ -27,6 +27,9 @@ libcrmservice_la_LDFLAGS	= -version-info 4:1:1
fada68
 libcrmservice_la_CPPFLAGS	= -DOCF_ROOT_DIR=\"@OCF_ROOT_DIR@\" $(AM_CPPFLAGS)
fada68
 libcrmservice_la_CFLAGS		= $(GIO_CFLAGS)
fada68
 
fada68
+libcrmservice_la_CFLAGS		+= $(CFLAGS_HARDENED_LIB)
fada68
+libcrmservice_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libcrmservice_la_LIBADD		= $(GIO_LIBS) $(top_builddir)/lib/common/libcrmcommon.la $(DBUS_LIBS)
fada68
 
fada68
 libcrmservice_la_SOURCES	= services.c services_linux.c
fada68
diff --git a/lib/transition/Makefile.am b/lib/transition/Makefile.am
fada68
index 9bc039e..4d6cd23 100644
fada68
--- a/lib/transition/Makefile.am
fada68
+++ b/lib/transition/Makefile.am
fada68
@@ -25,6 +25,9 @@ lib_LTLIBRARIES			= libtransitioner.la
fada68
 libtransitioner_la_LDFLAGS	= -version-info 2:5:0
fada68
 libtransitioner_la_CPPFLAGS	= -I$(top_builddir) $(AM_CPPFLAGS)
fada68
 
fada68
+libtransitioner_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libtransitioner_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libtransitioner_la_LIBADD	= $(top_builddir)/lib/common/libcrmcommon.la
fada68
 libtransitioner_la_SOURCES	= unpack.c graph.c utils.c
fada68
 
fada68
diff --git a/lrmd/Makefile.am b/lrmd/Makefile.am
fada68
index 64df105..5846503 100644
fada68
--- a/lrmd/Makefile.am
fada68
+++ b/lrmd/Makefile.am
fada68
@@ -30,6 +30,9 @@ if BUILD_SYSTEMD
fada68
 systemdunit_DATA	= pacemaker_remote.service
fada68
 endif
fada68
 
fada68
+lrmd_CFLAGS		= $(CFLAGS_HARDENED_EXE)
fada68
+lrmd_LDFLAGS		= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 lrmd_LDADD		= $(top_builddir)/lib/common/libcrmcommon.la	\
fada68
 			$(top_builddir)/lib/services/libcrmservice.la	\
fada68
 			$(top_builddir)/lib/lrmd/liblrmd.la		\
fada68
@@ -38,6 +41,9 @@ lrmd_SOURCES		= main.c lrmd.c
fada68
 
fada68
 pacemaker_remoted_CPPFLAGS	= -DSUPPORT_REMOTE $(AM_CPPFLAGS)
fada68
 
fada68
+pacemaker_remoted_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+pacemaker_remoted_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 pacemaker_remoted_LDADD		= $(lrmd_LDADD)
fada68
 pacemaker_remoted_SOURCES	= main.c lrmd.c tls_backend.c ipc_proxy.c
fada68
 
fada68
diff --git a/mcp/Makefile.am b/mcp/Makefile.am
fada68
index 195530a..074d251 100644
fada68
--- a/mcp/Makefile.am
fada68
+++ b/mcp/Makefile.am
fada68
@@ -31,6 +31,9 @@ endif
fada68
 
fada68
 noinst_HEADERS		= pacemaker.h
fada68
 
fada68
+pacemakerd_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+pacemakerd_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
+
fada68
 pacemakerd_LDADD	= $(top_builddir)/lib/cluster/libcrmcluster.la $(top_builddir)/lib/common/libcrmcommon.la
fada68
 pacemakerd_LDADD	+= $(CLUSTERLIBS)
fada68
 pacemakerd_SOURCES	= pacemaker.c corosync.c
fada68
diff --git a/pacemaker.spec.in b/pacemaker.spec.in
fada68
index 6024514..a607588 100644
fada68
--- a/pacemaker.spec.in
fada68
+++ b/pacemaker.spec.in
fada68
@@ -63,6 +63,9 @@
fada68
 # Turn off cman support on platforms that normally ship with it
fada68
 %bcond_without cman
fada68
 
fada68
+# Turn off hardening of libraries and daemon executables
fada68
+%bcond_without hardening
fada68
+
fada68
 %if %{with profiling}
fada68
 # This disables -debuginfo package creation and also the stripping binaries/libraries
fada68
 # Useful if you want sane profiling data
fada68
@@ -168,6 +171,7 @@ resource health.
fada68
 
fada68
 Available rpmbuild rebuild options:
fada68
   --with(out) : cman stonithd doc coverage profiling pre_release upstart_job
fada68
+                hardening
fada68
 
fada68
 %package cli
fada68
 License:       GPLv2+ and LGPLv2+
fada68
@@ -301,6 +305,18 @@ find . -exec touch \{\} \;
fada68
 # Early versions of autotools (e.g. RHEL <= 5) do not support --docdir
fada68
 export docdir=%{pcmk_docdir}
fada68
 
fada68
+%if %{with hardening}
fada68
+# prefer distro-provided hardening flags in case they are defined
fada68
+# through _hardening_{c,ld}flags macros, configure script will
fada68
+# use its own defaults otherwise; if such hardenings are completely
fada68
+# undesired, rpmbuild using "--without hardening"
fada68
+# (or "--define '_without_hardening 1'")
fada68
+export CFLAGS_HARDENED_EXE="%{?_hardening_cflags}"
fada68
+export CFLAGS_HARDENED_LIB="%{?_hardening_cflags}"
fada68
+export LDFLAGS_HARDENED_EXE="%{?_hardening_ldflags}"
fada68
+export LDFLAGS_HARDENED_LIB="%{?_hardening_ldflags}"
fada68
+%endif
fada68
+
fada68
 ./autogen.sh
fada68
 
fada68
 %{configure}                                       \
fada68
@@ -309,6 +325,7 @@ export docdir=%{pcmk_docdir}
fada68
         %{!?with_cman:       --without-cman}       \
fada68
         --without-heartbeat                        \
fada68
         %{!?with_doc:        --with-brand=}        \
fada68
+        %{!?with_hardening:  --disable-hardening}  \
fada68
         --with-initdir=%{_initrddir}               \
fada68
         --localstatedir=%{_var}                    \
fada68
         --with-version=%{version}-%{release}
fada68
diff --git a/pengine/Makefile.am b/pengine/Makefile.am
fada68
index 96c914f..d4dbfb9 100644
fada68
--- a/pengine/Makefile.am
fada68
+++ b/pengine/Makefile.am
fada68
@@ -61,12 +61,18 @@ endif
fada68
 noinst_HEADERS	= allocate.h utils.h pengine.h
fada68
 
fada68
 libpengine_la_LDFLAGS	= -version-info 11:0:1
fada68
+
fada68
+libpengine_la_CFLAGS	= $(CFLAGS_HARDENED_LIB)
fada68
+libpengine_la_LDFLAGS	+= $(LDFLAGS_HARDENED_LIB)
fada68
+
fada68
 libpengine_la_LIBADD	= $(top_builddir)/lib/pengine/libpe_status.la \
fada68
 			$(top_builddir)/lib/cib/libcib.la
fada68
 # -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version
fada68
 libpengine_la_SOURCES	= pengine.c allocate.c utils.c constraints.c
fada68
 libpengine_la_SOURCES	+= native.c group.c clone.c master.c graph.c utilization.c
fada68
 
fada68
+pengine_CFLAGS	= $(CFLAGS_HARDENED_EXE)
fada68
+pengine_LDFLAGS	= $(LDFLAGS_HARDENED_EXE)
fada68
 pengine_LDADD	= $(top_builddir)/lib/cib/libcib.la $(COMMONLIBS)
fada68
 # libcib for get_object_root()
fada68
 #		$(top_builddir)/lib/hbclient/libhbclient.la
fada68
-- 
fada68
1.8.3.1
fada68
fada68
fada68
From 35ec27112452f2bd06ae8b395d8543db935e2b05 Mon Sep 17 00:00:00 2001
fada68
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
fada68
Date: Wed, 22 Jun 2016 15:18:00 +0200
fada68
Subject: [PATCH 2/2] Build: configure.ac: prefer as-needed linking in case of
fada68
 "-z now"
fada68
fada68
Slight optimization of a default toolchain-flags-based hardening.
fada68
---
fada68
 configure.ac | 12 +++++++++++-
fada68
 1 file changed, 11 insertions(+), 1 deletion(-)
fada68
fada68
diff --git a/configure.ac b/configure.ac
fada68
index edf6a91..4beb877 100644
fada68
--- a/configure.ac
fada68
+++ b/configure.ac
fada68
@@ -1914,7 +1914,10 @@ elif test "x${HARDENING}" = "xyes" \
fada68
 			 pie=1]
fada68
 		)
fada68
 	fi
fada68
-	# daemons incl. libs: full RELRO if sensible
fada68
+	# daemons incl. libs: full RELRO if sensible + as-needed linking
fada68
+	#                     so as to possibly mitigate startup performance
fada68
+	#                     hit caused by excessive linking with unneeded
fada68
+	#                     libraries
fada68
 	if test "${relro}" = 1 && test "${pie}" = 1; then
fada68
 		flag="-Wl,-z,now"
fada68
 		CC_CHECK_LDFLAGS(["${flag}"],
fada68
@@ -1923,6 +1926,13 @@ elif test "x${HARDENING}" = "xyes" \
fada68
 			 bindnow=1]
fada68
 		)
fada68
 	fi
fada68
+	if test "${bindnow}" = 1; then
fada68
+		flag="-Wl,--as-needed"
fada68
+		CC_CHECK_LDFLAGS(["${flag}"],
fada68
+			[LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}";
fada68
+			 LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}"]
fada68
+		)
fada68
+	fi
fada68
 	# universal: prefer strong > all > default stack protector if possible
fada68
 	flag=
fada68
 	if cc_supports_flag -fstack-protector-strong; then
fada68
-- 
fada68
1.8.3.1
fada68