[PATCH v3 2/5] Make libc symbols hidden in static PIE

Szabolcs Nagy szabolcs.nagy@arm.com
Fri Jan 15 11:25:24 GMT 2021


The 01/14/2021 19:36, H.J. Lu wrote:
> On Thu, Jan 14, 2021 at 3:18 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> > The 01/13/2021 09:50, Szabolcs Nagy via Libc-alpha wrote:
> > There are targets (i686) where hidden visibility functions are
> > problematic in PIE code so hidden cannot be applied to all symbols.
> > Then static PIE requires extern object access without relocations
> > (e.g. by relying on copy relocations in shared libraries instead of
> > GOT access in PIE code). See bug 14961.
> 
> It isn't about copy relocations.  It is IFUNC, PLT and PIE.   I needed
> additional patches to make static PIE to work on i386 and x86-64.
> I am enclosing my patches.  Please include them in your patch set.

it is about avoiding GOT for object access, which copy
relocations can do. hidden does it better, but you said
that does not work on i686 so i removed it (assuming
you know the implications: every pie object access must
be local and copy relocated in shared libraries)

morally all symbols should be hidden in static pie
because everything is local (the code is only linked
into static exectuables). this is useful outside the
start code too to avoid GOT indirections.

i686 does not want to set up EBX for hidden extern calls,
which is needed for ifuncs, so making everything hidden
does not work.

options:

(1) fix extern hidden pie calls on i686 (by making
    them the same as default vis pie calls so ifuncs
    work).

(2) annotate ifuncs (avoid hidden for them, ifuncs
    cannot appear in early start code anyway because
    of IRELATIVE): this can be difficult to maintain.

(3) annotate early object accesses to be hidden so
    RELATIVE relocs are avoided. (most targets want
    all objects to be hidden, but this solves bug
    27072 without causing problems on i686)

(4) make pie always use copy relocations on i686.
    (and then no hidden annotation is needed, object
    access is always local in pie).

my patches assumed (4), but that seems to not work so
i think doing (3) is reasonable: you either need a few
carefully placed 'pragma GCC visibility push(hidden)'
or an attribute_hidden_pie_data on object declarations
that may be used by the early start code.

> From 15488890220a8c580689e6f78a38847853b78850 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 14 Jan 2021 18:39:24 -0800
> Subject: [PATCH 1/4] libmvec: Add extra-test-objs to test-extras
> 
> Add extra-test-objs to test-extras so that they are compiled with
> -DMODULE_NAME=testsuite instead of -DMODULE_NAME=libc.

this makes sense.

> From e1e10cd6bd52d9061f138f49b35d4939e1cd5692 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 14 Jan 2021 16:40:43 -0800
> Subject: [PATCH 2/4] Make all symbols used by _dl_relocate_static_pie hidden
> 
> On i386, all calls to IFUNC functions must go through PLT and calls to
> hidden functions CANNOT go through PLT in PIE since EBX used in PIE PLT
> may not be set up for local calls to hidden IFUNC functions.
> 
> Even if we can't make all libc symbols hidden for static PIE on i386, we
> must make all symbols used by _dl_relocate_static_pie hidden.
> ---
>  elf/dl-reloc-static-pie.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
> index a8d964061e..cc34c2d2fe 100644
> --- a/elf/dl-reloc-static-pie.c
> +++ b/elf/dl-reloc-static-pie.c
> @@ -17,6 +17,7 @@
>     <https://www.gnu.org/licenses/>.  */
>  
>  #if ENABLE_STATIC_PIE
> +#pragma GCC visibility push(hidden)

yes, this is option (3). you will also need it in _dl_aux_init
and __libc_init_secure and __tunables_init.

> From c5ffa46591550d945b009f0e3bcf66603d48ac0b Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Thu, 14 Jan 2021 13:26:29 -0800
> Subject: [PATCH 3/4] i386: Call _dl_aux_init after relocating static PIE
> 
> In i386 static PIE, we need to call _dl_aux_init after relocating static
> PIE so that symbol addresses in _dl_aux_init and ARCH_SETUP_TLS are in
> sync.  Also in i386 static PIE, since __libc_init_secure is called before
> ARCH_SETUP_TLS, it must use "int $0x80" for system calls.  Update
> __libc_init_secure to use __geteuid_startup, __getuid_startup,
> __getegid_startup and __getgid_startup.

the syscall part i understand, but auxv vs tls i don't:

i thought you only need to ensure that objects are hidden
visibility in _dl_aux_init.

i think the dependency order is:

1 auxv
2 libc_secure
3 tunables
4 cpu features
5 self reloc
6 setup _dl_phdr from __ehdr_start
7 setup tls

i got 6 wrong in my patch: setup tls can use _dl_phdr,
i will fix it.

moving auxv a bit later is possible (if you don't mind
syscalls in libc_secure and nothing requires it in
cpu features), but i don't see how that's related to
tls.


More information about the Libc-alpha mailing list