On Thu, Nov 30, 2017 at 1:44 PM, Carlos O'Donell wrote: > H.J., > > High Level: > > At a high level I have no objection with the idea of static PIE executables, > it makes sense to support such things. Thanks for your feedbacks. > My only nit is that we need to do a better job of explaining to users why > they would use them and under what circumstances. To that end you have a bit > more work to do in the commit message, install.texit, and NEWS entry. > > Design: > > I have one design question below which around testing static non-PIE executables > in a --enable-static-pie build. See below. > > Implementation: > > Everything looks good except the use of firstword in +link-static-before-libc, > which I describe below. I think this is a hack and should be changed to better > represent the expected semantics and structure you are looking to support. Fixed. > Thank you for your work in this area. > > Look forward to a v2. > >> From 7026a79c1f71f5decd135208503fd4186193ffb8 Mon Sep 17 00:00:00 2001 >> From: "H.J. Lu" >> Date: Mon, 17 Jul 2017 08:17:32 -0700 >> Subject: [PATCH] Add --enable-static-pie configure option to build static PIE >> [BZ #19574] >> >> Dynamic linker, ld.so, is a standalone program which can be loaded at >> any address. This patch adds a configure option, --enable-static-pie, >> to embed the part of ld.so in static executable to create static position >> independent executable (static PIE). A static PIE is similar to static >> executable, but can be loaded at any address without help from a dynamic >> linker. When --enable-static-pie is used to configure glibc, libc.a is >> built as PIE and all static executables, including tests, are built as >> static PIE. The resulting libc.a can be used together with GCC 8 or >> above to build static PIE with the compiler option, -static-pie. But >> GCC 8 isn't required to build glibc with --enable-static-pie. When an >> older GCC is used to build glibc with --enable-static-pie, proper input >> files are passed to linker to create static executables as static PIE, >> together with "-z text" to prevent dynamic relocations in read-only >> segments, which are allowed in static PIE. > > You write "which are allowed", shouldn't that be "which are not allowed"? Fixed. > The commit message must explain the following: > > * Why would a user use this feature? > - What does it provide over and beyond existing static executables > > * How does a user decide to use this feature? > - Should everyone use it? > - Should you use it if you care about security, and what does it cost? > > Please include the answers to these questions in a the next versions > commit message. I added : Static PIE extends address space layout randomization to static executables. It provides additional security hardening benefits at the cost of some memory and performance. Is this OK? >> @@ -420,7 +440,7 @@ endif >> # Command for statically linking programs with the C library. >> ifndef +link-static >> +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \ >> - $(DEFAULT-LDFLAGS-$(@F)) \ >> + $(firstword $(DEFAULT-LDFLAGS-$(@F)) $(default-pie-ldflag)) \ > > Is the use of firstword here just a hack to put $(no-pie-ldflag) first so > you can override it with the subsequent $(default-pie-ldflag)? > > It is not a robust design to use firstword here because it implies that the > DEFAUTL-LDFLAGS-$(@F) has some structure that we are not documenting. > > I would like to see this done some other way. My preference would be for a new > value other than DEFAULT-LDFLAGS to control the PIE-ness of the built progarm. > I replaced DEFAUTL-LDFLAGS-$(@F) with $($(@F)-no-pie). Now I have # Command for statically linking programs with the C library. ifndef +link-static +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \ - $(DEFAULT-LDFLAGS-$(@F)) \ + $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ >> >> diff --git a/NEWS b/NEWS >> index ab14d1eb1b..61598be94d 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -9,6 +9,11 @@ Version 2.27 >> >> Major new features: >> >> +* Add --enable-static-pie configure option to build static PIE. The >> + resulting libc.a can be used with the GCC option, -static-pie, which >> + is available with GCC 8 or above, to create static position independent >> + executable (static PIE). >> + > > The description of a new configure option is relevant only to INSTALL. > > We must explain when users would use this feature and why. NEWS entries are > user facing and must explain the function of the new feature. Does it improve > security for static binaries? Should users switch to using them instead of > normal static binaries? > > Lastly, we must explain which machines are supported in this initial release > of the feature. Only x86_64? You need not check all machines, other maintainers > can check and adjust the NEWS entry, but we have to commit to at least one > machine supporting this feature, which I assume is x86_64. > > For example: > > * The GNU C Library can now be compiled with support for building static > PIE executables (See --enable-static-pie in INSTALL). These static PIE > exectuables are like static executables but can be loaded at any address > and provide additional security hardening benefits at the cost of some > memory and performance. When the library is built with --enable-static-pie > the resulting libc.a is usable with GCC 8 and above to create static PIE > executables using the GCC option '-static-pie'. This feature is currently > supported on x86_64. > I took your example. Thanks. > >> diff --git a/configure.ac b/configure.ac >> index 8ebc490a55..ae219f8fe0 100644 >> --- a/configure.ac >> +++ b/configure.ac >> @@ -176,6 +176,11 @@ AC_ARG_ENABLE([profile], >> [build profiled library @<:@default=no@:>@]), >> [profile=$enableval], >> [profile=no]) >> +AC_ARG_ENABLE([static-pie], >> + AC_HELP_STRING([--enable-static-pie], >> + [build static executables as PIE @<:@default=no@:>@]), > > This does 2 things: > * It enables support for building static PIE executables. > * It builds all static binaries and tests in the testsuite as static PIE executables. > > It should say that e.g. > > "Enable static PIE executable support and use it in the testsuite." > > I understand the desire to use such a functionality to test static PIE executables > by converting the entire testsuite to use them, but we still need to test non-PIE > static executables? How are we still doing that after this change? > > How are we testing non-PIE static executables after this change? This is similar to PIE vs non-PIE. When you build glibc with GCC defaulting to PIE, most of dynamic tests are built as PIE, except for a couple of them linked with $(no-pie-ldflag). I added elf/tst-tls1-static-non-pie.c which is always built as non-PIE static executable, regardless if --enable-static-pie is used to configure glibc. To get better coverage for non-PIE, we need to build glibc with GCC defaulting to non-PIE and configure glibc without --enable-static-pie. >> diff --git a/manual/install.texi b/manual/install.texi >> index f1fa28c937..86193ade3f 100644 >> --- a/manual/install.texi >> +++ b/manual/install.texi >> @@ -120,6 +120,13 @@ Don't build shared libraries even if it is possible. Not all systems >> support shared libraries; you need ELF support and (currently) the GNU >> linker. >> >> +@item --enable-static-pie > > This should be rewritten to explain the feature that it enables first, > and then the ancilliary benefits like turning it on in the testsuite. > >> +Build static executables, including tests, as position independent >> +executable (static PIE) which is similar to static executable, but can >> +be loaded at any address without help from a dynamic linker. The >> +resulting libc.a can be used with the GCC option, -static-pie, which >> +is available with GCC 8 or above, to create static PIE. >> + I changed it to '--enable-static-pie' Enable static position independent executable (static PIE) support. Static PIE is similar to static executable, but can be loaded at any address without help from a dynamic linker. All static programs as well as static tests are built as static PIE, except for those marked with no-pie. The resulting glibc can be used with the GCC option, -static-pie, which is available with GCC 8 or above, to create static PIE. Here is the updated patch. Using GCC 7 and binutils master branch, build-many-glibcs.py with --enable-static-pie with all patches for static PIE applied have the following build successes: PASS: glibcs-aarch64_be-linux-gnu build PASS: glibcs-aarch64-linux-gnu build PASS: glibcs-armeb-linux-gnueabi-be8 build PASS: glibcs-armeb-linux-gnueabi build PASS: glibcs-armeb-linux-gnueabihf-be8 build PASS: glibcs-armeb-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabi build PASS: glibcs-arm-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabihf-v7a build PASS: glibcs-arm-linux-gnueabihf-v7a-disable-multi-arch build PASS: glibcs-m68k-linux-gnu build PASS: glibcs-microblazeel-linux-gnu build PASS: glibcs-microblaze-linux-gnu build PASS: glibcs-mips64el-linux-gnu-n32 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n32-soft build PASS: glibcs-mips64el-linux-gnu-n64 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n64-soft build PASS: glibcs-mips64-linux-gnu-n32 build PASS: glibcs-mips64-linux-gnu-n32-nan2008 build PASS: glibcs-mips64-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n32-soft build PASS: glibcs-mips64-linux-gnu-n64 build PASS: glibcs-mips64-linux-gnu-n64-nan2008 build PASS: glibcs-mips64-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n64-soft build PASS: glibcs-mipsel-linux-gnu build PASS: glibcs-mipsel-linux-gnu-nan2008 build PASS: glibcs-mipsel-linux-gnu-nan2008-soft build PASS: glibcs-mipsel-linux-gnu-soft build PASS: glibcs-mips-linux-gnu build PASS: glibcs-mips-linux-gnu-nan2008 build PASS: glibcs-mips-linux-gnu-nan2008-soft build PASS: glibcs-mips-linux-gnu-soft build PASS: glibcs-nios2-linux-gnu build PASS: glibcs-powerpc64le-linux-gnu build PASS: glibcs-powerpc64-linux-gnu build PASS: glibcs-tilegxbe-linux-gnu-32 build PASS: glibcs-tilegxbe-linux-gnu build PASS: glibcs-tilegx-linux-gnu-32 build PASS: glibcs-tilegx-linux-gnu build PASS: glibcs-tilepro-linux-gnu build I don't know how many of them actually work, except for aarch64. Thanks. -- H.J.