[libvirt] [PATCH 0/2] Improve security hardening of binaries

Fedora has a "hardened build" option in RPM specfiles: https://fedoraproject.org/wiki/Packaging:Guidelines#PIE While we could enable that in the RPM, this would only apply to Fedora. Thus these patches directly integrate it in libvirt's configure.ac / Makefile.am files. With these 2 patches all executables gain -fPIE and -z relro -z now. Using the checksec.sh script from http://www.trapkit.de/tools/checksec.html We can see the difference, before: $ ~/checksec.sh --file /usr/sbin/libvirtd 'RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH /usr/sbin/libvirtd After $ ~/checksec.sh --file /usr/sbin/libvirtd 'RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH /usr/sbin/libvirtd

From: "Daniel P. Berrange" <berrange@redhat.com> PIE (position independent executable) adds security to executables by composing them entirely of position-independent code (PIC. The .so libraries already build with -fPIC. This adds -fPIE which is the equivalent to -fPIC, but for executables. This for allows Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- configure.ac | 1 + daemon/Makefile.am | 5 +++-- m4/virt-compile-pie.m4 | 13 ++++++++++++ src/Makefile.am | 57 +++++++++++++++++++++++++++++++++++++++++--------- tools/Makefile.am | 6 +++++- 5 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 m4/virt-compile-pie.m4 diff --git a/configure.ac b/configure.ac index 09e4ad9..69d87fc 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,7 @@ VERSION_SCRIPT_FLAGS=-Wl,--version-script= AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS]) LIBVIRT_COMPILE_WARNINGS +LIBVIRT_COMPILE_PIE LIBVIRT_CHECK_APPARMOR LIBVIRT_CHECK_ATTR diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 4d5c2fd..bf260b1 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -106,12 +106,13 @@ libvirtd_SOURCES = $(DAEMON_SOURCES) libvirtd_CFLAGS = \ $(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \ $(XDR_CFLAGS) $(POLKIT_CFLAGS) $(DBUS_CFLAGS) $(LIBNL_CFLAGS) \ - $(WARN_CFLAGS) \ + $(WARN_CFLAGS) $(PIE_CFLAGS) \ $(COVERAGE_CFLAGS) \ -DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\"" libvirtd_LDFLAGS = \ - $(WARN_CFLAGS) \ + $(WARN_LDFLAGS) \ + $(PIE_LDFLAGS) \ $(COVERAGE_LDFLAGS) libvirtd_LDADD = \ diff --git a/m4/virt-compile-pie.m4 b/m4/virt-compile-pie.m4 new file mode 100644 index 0000000..fc2d444 --- /dev/null +++ b/m4/virt-compile-pie.m4 @@ -0,0 +1,13 @@ +dnl +dnl Check for support for position independent executables +dnl +AC_DEFUN([LIBVIRT_COMPILE_PIE],[ + PIE_CFLAGS= + PIE_LDFLAGS= + gl_COMPILER_OPTION_IF([-fPIE -DPIE], [ + PIE_CFLAGS="-fPIE -DPIE" + PIE_LDFLAGS="-pie" + ]) + AC_SUBST([PIE_CFLAGS]) + AC_SUBST([PIE_LDFLAGS]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index 3f69d39..b33737f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1670,9 +1670,11 @@ virtlockd_SOURCES = \ $(NULL) virtlockd_CFLAGS = \ $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ $(NULL) virtlockd_LDFLAGS = \ $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ $(CYGWIN_EXTRA_LDFLAGS) \ $(MINGW_EXTRA_LDFLAGS) \ $(NULL) @@ -1917,7 +1919,11 @@ libexec_PROGRAMS = if WITH_LIBVIRTD libexec_PROGRAMS += libvirt_iohelper libvirt_iohelper_SOURCES = $(UTIL_IO_HELPER_SOURCES) -libvirt_iohelper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS) +libvirt_iohelper_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) libvirt_iohelper_LDADD = \ libvirt_util.la \ ../gnulib/lib/libgnu.la @@ -1925,7 +1931,10 @@ if WITH_DTRACE_PROBES libvirt_iohelper_LDADD += libvirt_probes.lo endif -libvirt_iohelper_CFLAGS = $(AM_CFLAGS) +libvirt_iohelper_CFLAGS = \ + $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ + $(NULL) endif if WITH_STORAGE_DISK @@ -1933,7 +1942,11 @@ if WITH_LIBVIRTD libexec_PROGRAMS += libvirt_parthelper libvirt_parthelper_SOURCES = $(STORAGE_HELPER_DISK_SOURCES) -libvirt_parthelper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS) +libvirt_parthelper_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) libvirt_parthelper_LDADD = \ $(LIBPARTED_LIBS) \ libvirt_util.la \ @@ -1942,7 +1955,11 @@ if WITH_DTRACE_PROBES libvirt_parthelper_LDADD += libvirt_probes.lo endif -libvirt_parthelper_CFLAGS = $(LIBPARTED_CFLAGS) $(AM_CFLAGS) +libvirt_parthelper_CFLAGS = \ + $(LIBPARTED_CFLAGS) \ + $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ + $(NULL) endif endif EXTRA_DIST += $(STORAGE_HELPER_DISK_SOURCES) @@ -1952,8 +1969,16 @@ if WITH_SANLOCK libexec_PROGRAMS += libvirt_sanlock_helper libvirt_sanlock_helper_SOURCES = $(LOCK_DRIVER_SANLOCK_HELPER_SOURCES) -libvirt_sanlock_helper_CFLAGS = -I$(top_srcdir)/src/conf $(AM_CFLAGS) -libvirt_sanlock_helper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS) +libvirt_sanlock_helper_CFLAGS = \ + -I$(top_srcdir)/src/conf \ + $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ + $(NULL) +libvirt_sanlock_helper_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) libvirt_sanlock_helper_LDADD = libvirt.la endif @@ -1965,7 +1990,11 @@ libvirt_lxc_SOURCES = \ $(LXC_CONTROLLER_SOURCES) \ $(NODE_INFO_SOURCES) \ $(DATATYPES_SOURCES) -libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS) +libvirt_lxc_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) libvirt_lxc_LDADD = \ $(FUSE_LIBS) \ libvirt-net-rpc-server.la \ @@ -1981,8 +2010,10 @@ libvirt_lxc_LDADD += $(SECDRIVER_LIBS) libvirt_lxc_CFLAGS = \ -I$(top_srcdir)/src/conf \ $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ $(LIBNL_CFLAGS) \ - $(FUSE_CFLAGS) + $(FUSE_CFLAGS) \ + $(NULL) if WITH_BLKID libvirt_lxc_CFLAGS += $(BLKID_CFLAGS) libvirt_lxc_LDADD += $(BLKID_LIBS) @@ -2003,7 +2034,11 @@ libexec_PROGRAMS += virt-aa-helper virt_aa_helper_SOURCES = $(SECURITY_DRIVER_APPARMOR_HELPER_SOURCES) -virt_aa_helper_LDFLAGS = $(WARN_LDFLAGS) $(AM_LDFLAGS) +virt_aa_helper_LDFLAGS = \ + $(WARN_LDFLAGS) \ + $(AM_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NULL) virt_aa_helper_LDADD = \ libvirt_conf.la \ libvirt_util.la \ @@ -2014,7 +2049,9 @@ endif virt_aa_helper_CFLAGS = \ -I$(top_srcdir)/src/conf \ -I$(top_srcdir)/src/security \ - $(AM_CFLAGS) + $(AM_CFLAGS) \ + $(PIE_CFLAGS) \ + $(NULL) endif endif EXTRA_DIST += $(SECURITY_DRIVER_APPARMOR_HELPER_SOURCES) diff --git a/tools/Makefile.am b/tools/Makefile.am index 0010c39..09a9bdd 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -99,6 +99,7 @@ virt_host_validate_SOURCES = \ virt_host_validate_LDFLAGS = \ $(WARN_LDFLAGS) \ + $(PIE_LDFLAGS) \ $(COVERAGE_LDFLAGS) \ $(NULL) @@ -109,6 +110,7 @@ virt_host_validate_LDADD = \ virt_host_validate_CFLAGS = \ $(WARN_CFLAGS) \ + $(PIE_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(NULL) @@ -131,7 +133,8 @@ virsh_SOURCES = \ virsh_LDFLAGS = $(WARN_LDFLAGS) $(COVERAGE_LDFLAGS) virsh_LDADD = \ $(STATIC_BINARIES) \ - $(WARN_CFLAGS) \ + $(WARN_LDFLAGS) \ + $(PIE_LDFLAGS) \ ../src/libvirt.la \ ../src/libvirt-lxc.la \ ../src/libvirt-qemu.la \ @@ -140,6 +143,7 @@ virsh_LDADD = \ $(VIRSH_LIBS) virsh_CFLAGS = \ $(WARN_CFLAGS) \ + $(PIE_CFLAGS) \ $(COVERAGE_CFLAGS) \ $(LIBXML_CFLAGS) \ $(READLINE_CFLAGS) -- 1.7.11.7

On 04/03/2013 05:41 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
PIE (position independent executable) adds security to executables by composing them entirely of position-independent code (PIC. The .so libraries already build with -fPIC. This adds -fPIE which is the equivalent to -fPIC, but for executables. This for allows Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> ---
+++ b/m4/virt-compile-pie.m4 @@ -0,0 +1,13 @@ +dnl +dnl Check for support for position independent executables
This new file is currently small enough to get away with no copyright notice, but adding one now would be easier than scratching our heads during a later audit on whether it is needed. ACK, whether or not you add a copyright blurb to the new .m4 file. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> By passing the flags -z relro -z now to the linker, we can force it to resolve all library symbols at startup, instead of on-demand. This allows it to then make the global offset table (GOT) read-only, which makes some security attacks harder. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- configure.ac | 1 + daemon/Makefile.am | 1 + m4/virt-linker-relro.m4 | 15 +++++++++++++++ src/Makefile.am | 43 +++++++++++++++++++++++++++++++------------ tools/Makefile.am | 2 ++ 5 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 m4/virt-linker-relro.m4 diff --git a/configure.ac b/configure.ac index 69d87fc..4c93e7d 100644 --- a/configure.ac +++ b/configure.ac @@ -142,6 +142,7 @@ AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS]) LIBVIRT_COMPILE_WARNINGS LIBVIRT_COMPILE_PIE +LIBVIRT_LINKER_RELRO LIBVIRT_CHECK_APPARMOR LIBVIRT_CHECK_ATTR diff --git a/daemon/Makefile.am b/daemon/Makefile.am index bf260b1..3532bd5 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -113,6 +113,7 @@ libvirtd_CFLAGS = \ libvirtd_LDFLAGS = \ $(WARN_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(COVERAGE_LDFLAGS) libvirtd_LDADD = \ diff --git a/m4/virt-linker-relro.m4 b/m4/virt-linker-relro.m4 new file mode 100644 index 0000000..eeff0f8 --- /dev/null +++ b/m4/virt-linker-relro.m4 @@ -0,0 +1,15 @@ +dnl +dnl Check for -z now and -z relro linker flags +dnl +AC_DEFUN([LIBVIRT_LINKER_RELRO],[ + AC_MSG_CHECKING([for how to force completely read-only GOT table]) + + RELRO_LDFLAGS= + `$LD --help 2>&1 | grep -- "-z relro" >/dev/null` && \ + RELRO_LDFLAGS="-Wl,-z -Wl,relro" + `$LD --help 2>&1 | grep -- "-z now" >/dev/null` && \ + RELRO_LDFLAGS="$RELRO_LDFLAGS -Wl,-z -Wl,now" + AC_SUBST([RELRO_LDFLAGS]) + + AC_MSG_RESULT([$RELRO_LDFLAGS]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index b33737f..78b4ab6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1537,10 +1537,15 @@ libvirt_lxc.def: $(srcdir)/libvirt_lxc.syms # Empty source list - it merely links a bunch of convenience libs together libvirt_la_SOURCES = -libvirt_la_LDFLAGS = $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_SYMBOL_FILE) \ - -version-info $(LIBVIRT_VERSION_INFO) \ - $(LIBVIRT_NODELETE) $(AM_LDFLAGS) \ - $(CYGWIN_EXTRA_LDFLAGS) $(MINGW_EXTRA_LDFLAGS) +libvirt_la_LDFLAGS = \ + $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_SYMBOL_FILE) \ + -version-info $(LIBVIRT_VERSION_INFO) \ + $(LIBVIRT_NODELETE) \ + $(AM_LDFLAGS) \ + $(RELRO_LDFLAGS) \ + $(CYGWIN_EXTRA_LDFLAGS) \ + $(MINGW_EXTRA_LDFLAGS) \ + $(NULL) libvirt_la_BUILT_LIBADD += ../gnulib/lib/libgnu.la libvirt_la_LIBADD += \ $(DRIVER_MODULE_LIBS) \ @@ -1616,18 +1621,26 @@ endif EXTRA_DIST += libvirt_probes.d libvirt_qemu_probes.d libvirt_qemu_la_SOURCES = libvirt-qemu.c -libvirt_qemu_la_LDFLAGS = $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_QEMU_SYMBOL_FILE) \ - -version-info $(LIBVIRT_VERSION_INFO) \ - $(CYGWIN_EXTRA_LDFLAGS) $(MINGW_EXTRA_LDFLAGS) \ - $(AM_LDFLAGS) +libvirt_qemu_la_LDFLAGS = \ + $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_QEMU_SYMBOL_FILE) \ + -version-info $(LIBVIRT_VERSION_INFO) \ + $(AM_LDFLAGS) \ + $(RELRO_LDFLAGS) \ + $(CYGWIN_EXTRA_LDFLAGS) \ + $(MINGW_EXTRA_LDFLAGS) \ + $(NULL) libvirt_qemu_la_CFLAGS = $(AM_CFLAGS) libvirt_qemu_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD) libvirt_lxc_la_SOURCES = libvirt-lxc.c -libvirt_lxc_la_LDFLAGS = $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_LXC_SYMBOL_FILE) \ - -version-info $(LIBVIRT_VERSION_INFO) \ - $(CYGWIN_EXTRA_LDFLAGS) $(MINGW_EXTRA_LDFLAGS) \ - $(AM_LDFLAGS) +libvirt_lxc_la_LDFLAGS = \ + $(VERSION_SCRIPT_FLAGS)$(LIBVIRT_LXC_SYMBOL_FILE) \ + -version-info $(LIBVIRT_VERSION_INFO) \ + $(AM_LDFLAGS) \ + $(RELRO_LDFLAGS) \ + $(CYGWIN_EXTRA_LDFLAGS) \ + $(MINGW_EXTRA_LDFLAGS) \ + $(NULL) libvirt_lxc_la_CFLAGS = $(AM_CFLAGS) libvirt_lxc_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD) EXTRA_DIST += $(LIBVIRT_LXC_SYMBOL_FILE) @@ -1675,6 +1688,7 @@ virtlockd_CFLAGS = \ virtlockd_LDFLAGS = \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(CYGWIN_EXTRA_LDFLAGS) \ $(MINGW_EXTRA_LDFLAGS) \ $(NULL) @@ -1923,6 +1937,7 @@ libvirt_iohelper_LDFLAGS = \ $(WARN_LDFLAGS) \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(NULL) libvirt_iohelper_LDADD = \ libvirt_util.la \ @@ -1946,6 +1961,7 @@ libvirt_parthelper_LDFLAGS = \ $(WARN_LDFLAGS) \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(NULL) libvirt_parthelper_LDADD = \ $(LIBPARTED_LIBS) \ @@ -1978,6 +1994,7 @@ libvirt_sanlock_helper_LDFLAGS = \ $(WARN_LDFLAGS) \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(NULL) libvirt_sanlock_helper_LDADD = libvirt.la endif @@ -1994,6 +2011,7 @@ libvirt_lxc_LDFLAGS = \ $(WARN_LDFLAGS) \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(NULL) libvirt_lxc_LDADD = \ $(FUSE_LIBS) \ @@ -2038,6 +2056,7 @@ virt_aa_helper_LDFLAGS = \ $(WARN_LDFLAGS) \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(NULL) virt_aa_helper_LDADD = \ libvirt_conf.la \ diff --git a/tools/Makefile.am b/tools/Makefile.am index 09a9bdd..07c9f43 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -100,6 +100,7 @@ virt_host_validate_SOURCES = \ virt_host_validate_LDFLAGS = \ $(WARN_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ $(COVERAGE_LDFLAGS) \ $(NULL) @@ -135,6 +136,7 @@ virsh_LDADD = \ $(STATIC_BINARIES) \ $(WARN_LDFLAGS) \ $(PIE_LDFLAGS) \ + $(RELRO_LDFLAGS) \ ../src/libvirt.la \ ../src/libvirt-lxc.la \ ../src/libvirt-qemu.la \ -- 1.7.11.7

On 04/03/2013 05:41 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
By passing the flags -z relro -z now to the linker, we can force it to resolve all library symbols at startup, instead of on-demand. This allows it to then make the global offset table (GOT) read-only, which makes some security attacks harder.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- configure.ac | 1 + daemon/Makefile.am | 1 + m4/virt-linker-relro.m4 | 15 +++++++++++++++ src/Makefile.am | 43 +++++++++++++++++++++++++++++++------------ tools/Makefile.am | 2 ++ 5 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 m4/virt-linker-relro.m4
+++ b/m4/virt-linker-relro.m4 @@ -0,0 +1,15 @@ +dnl +dnl Check for -z now and -z relro linker flags
Same comment about copyright blurb. ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Daniel P. Berrange
-
Eric Blake