This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Sun, Nov 19, 2017 at 7:39 AM, Florian Weimer <fw@deneb.enyo.de> wrote:
> * H. J. Lu:
>
>> The GCC driver patch has been checked into GCC 8.   Here is the updated
>> patch for glibc.
>>
>> Tested with build-many-glibcs.py.    Any objections?
>
> Is the entire text below supposed to go into the commit message?  What

Yes.

> about the remaining tasks listed in it?

Target maintainers must work with binutils maintainers to resolve them
since static PIE may require linker bug fixes.

>> 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.
>
> The last sentence is unclear.  Is -z text required to use a glibc
> compiled by an earlier GCC?  What exactly is the problem with dynamic
> relocations in read-only segments?  Are they allowed or disallowed?

ld.so is a special static PIE.  ld.so/static PIE can't have dynamic relocations
in read-only segments since static PIE is mapped into memory by KERNEL.
Unless we can want to change memory protection on read-only segments,
we can't have dynamic relocations in read-only segments.

> Can we support .data.relro?

Yes, that is supported since .data.relro section isn't in read-only segment:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00000034 0x00000034 0x00140 0x00140 R   0x4
  INTERP         0x172494 0x00172494 0x00172494 0x00013 0x00013 R   0x4
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x00000000 0x00000000 0x1b9c24 0x1b9c24 R E 0x1000
  LOAD           0x1ba218 0x001bb218 0x001bb218 0x02cdc 0x05804 RW  0x1000
  DYNAMIC        0x1bbd70 0x001bcd70 0x001bcd70 0x000f8 0x000f8 RW  0x4
  NOTE           0x000174 0x00000174 0x00000174 0x00044 0x00044 R   0x4
  TLS            0x1ba218 0x001bb218 0x001bb218 0x00008 0x00054 R   0x4
  GNU_EH_FRAME   0x1724a8 0x001724a8 0x001724a8 0x05bc4 0x05bc4 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x1ba218 0x001bb218 0x001bb218 0x01de8 0x01de8 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00
   01     .interp
   02     .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr
.gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt
.plt.got .text __libc_freeres_fn __libc_thread_freeres_fn .rodata
.stapsdt.base .interp .eh_frame_hdr .eh_frame .gcc_except_table .hash
   03     .tdata .init_array __libc_subfreeres __libc_atexit
__libc_thread_subfreeres __libc_IO_vtables .data.rel.ro .dynamic .got
.got.plt .data .bss
   04     .dynamic
   05     .note.gnu.build-id .note.ABI-tag
   06     .tdata .tbss
   07     .eh_frame_hdr
   08
   09     .tdata .init_array __libc_subfreeres __libc_atexit
__libc_thread_subfreeres __libc_IO_vtables .data.rel.ro .dynamic .got

It is in RELRO  segment, which is made read-only AFTER relocation is done.

>> Static PIE can work on all architectures which support PIE, provided:
>>
>> 1. Target must support accessing of local functions without dynamic
>> relocations, which is needed in start.S to call __libc_start_main with
>> function addresses of __libc_csu_init, __libc_csu_fini and main.
>
> Are there really ABI concerns for the statically linked case?  It
> should not be necessary to pass these function pointers.

I want to use the same internal function interface for static PIE and
normal binaries.

>> All functions in statice PIE are local functions.  If PIE start.S
>> can't
>
> Typo: “statice”

Fixed.

>> 6. __brk works without TLS nor dynamic relocations in read-only section
>> so that it can be used by __libc_setup_tls to initializes TLS in static
>> PIE.
>
> Note that some kernels have strange address space layouts which
> prevent __brk from working reliably.

__brk is used in static binary.  If static works, static PIE should be OK.

>
>> NB: When glibc is built with GCC defaulted to PIE, libc.a is compiled
>> with -fPIE, regardless if --enable-static-pie is used to configure glibc.
>> When glibc is configured with --enable-static-pie, libc.a is compiled
>> with -fPIE, regardless wether GCC defaults to PIE or not.  The same libc.a
>> can be used to build both static executable and static PIE.  There is no
>> need for separate PIE copy of libc.a.
>
> Is there a code size cost to PIE?

On x86-64, the normal static sln:

   text    data     bss     dec     hex filename
 625425    8284    5456  639165   9c0bd elf/sln

the static PIE sln:

   text    data     bss     dec     hex filename
 657626   20636    5392  683654   a6e86 elf/sln

The code size is increased by 5% and the binary size is increased by 7%.

>> Linker requirements to build glibc with --enable-static-pie:
>>
>> 1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from
>> static PIE.
>> 2. Linker can create working static PIE.  The x86-64 linker needs the
>> fix for
>>
>> https://sourceware.org/bugzilla/show_bug.cgi?id=21782
>
> So binutils 2.29 is the minimum requirement on x86-64?

Yes.

> Can an earlier binutils version be used to build a static library
> which is usable for PIE with binutils 2.29+?

Only linker is needed to create static PIE.  Since we don't need
a linker to create a static library, it should be OK.

>> +'--enable-static-pie'
>> +     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. Only
>> +     i686, x86-64 and x32 targets are verified to work.
>
> Drop the last sentence, it will be outdated soon.
>
>> diff --git a/Makeconfig b/Makeconfig
>
> The reason for some of the changes are not obvious at all to me, and
> the ChangeLog doesn't give an explanation either.

Can you list them so that I can address them?

>> new file mode 100644
>> index 0000000000..aa9302602b
>> --- /dev/null
>> +++ b/elf/dl-reloc-static-pie.c
>
> Is there anything which inhibits compilation of this file ith the
> stack protector?  I think this is necessary because
> _dl_relocate_static_pie is called so early.

Good point.  I will check.

>> +extern struct link_map * _dl_get_dl_main_map (void)
>> +  __attribute__ ((visibility ("hidden")));
>
> This should go into a header file somewhere, so that the declaration
> can be checked against the definition.

I will see what I can do.

>> diff --git a/elf/dl-support.c b/elf/dl-support.c
>> index 235d3a7f46..b9fc1a66fe 100644
>> --- a/elf/dl-support.c
>> +++ b/elf/dl-support.c
>> @@ -385,3 +385,14 @@ _dl_non_dynamic_init (void)
>>  #ifdef DL_SYSINFO_IMPLEMENTATION
>>  DL_SYSINFO_IMPLEMENTATION
>>  #endif
>> +
>> +#if ENABLE_STATIC_PIE
>> +/* Since relocation to hidden _dl_main_map causes relocation overflow on
>> +   aarch64, a function is used to get the address of _dl_main_map.  */
>> +
>> +struct link_map *
>> +_dl_get_dl_main_map (void)
>> +{
>> +  return &_dl_main_map;
>> +}
>> +#endif
>
> Is this issue really aarch64-specific, or could it affect other

I think only aarch64 is affected.  But I am not 100% sure.

> targets?

Thanks.

-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]