PING^N: [PATCH] Add --enable-static-pie to build static PIE [BZ #19574]

H.J. Lu hjl.tools@gmail.com
Fri Dec 1 18:24:00 GMT 2017


On Thu, Nov 30, 2017 at 1:44 PM, Carlos O'Donell <carlos@redhat.com> 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" <hjl.tools@gmail.com>
>> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Add-enable-static-pie-configure-option-to-build-stat.patch
Type: text/x-patch
Size: 45534 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20171201/57af6870/attachment.bin>


More information about the Libc-alpha mailing list