[PATCH] elf: Remove ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA
Szabolcs Nagy
szabolcs.nagy@arm.com
Tue May 31 08:12:11 GMT 2022
The 05/30/2022 23:48, Fangrui Song wrote:
> On 2022-05-30, Szabolcs Nagy wrote:
> > The 05/27/2022 21:42, Fangrui Song via Libc-alpha wrote:
> > > Say both a.so and b.so define protected var and the executable copy
> > > relocates var. ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has strange
> > > semantics: a.so accesses the copy in the executable while b.so accesses
> > > its own. This behavior requires that (a) the compiler emits
> > > GOT-generating relocations (b) the linker produces GLOB_DAT instead of
> > > RELATIVE. The behavior change is from commit
> > > 62da1e3b00b51383ffa7efc89d8addda0502e107 (x86) and then copied to nios2
> > > (ae5eae7cfc9c4a8297ff82ec6b794faca1976ecc) and arc
> > > (0e7d930c4c11de896fe807f67fa1eb756c9c1e05).
> > >
> > > Without the ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA code, b.so's GLOB_DAT
> > > will bind to the executable (normal behavior).
> >
> > i think this should be reworded so all of this is under
> > assumptions (a) and (b).
>
> How should I reword this, concretely? :)
how about:
If an executable has copy relocations for extern protected data, that
can only work if the library containing the definition is built with
assumptions (a) ... (b) ... . Otherwise the library uses its own
definition directly and the executable accesses a stale copy. Note:
the GOT relocations defeat the purpose of protected visibility as an
optimization, but allow the dynamic linker to make the executable and
library use the same copy when copy relocations are present, but it
turns out this never worked perfectly.
ELF_RTYPE_... has strange semantics when both a.so and b.so define
protected var and the executable copy relocates var: a.so accesses the
copy in ...
The behaviour change is from commit ...
Without the ELF_RTYPE_...
There is no change when copy relocations are not present or when only
one library has definition for a protected variable. It's extremely
unlikely that anyone relies on ...
> I think the tests currently XPASS on x86 with GNU ld and XFAIL on a
> bunch of architectures. I do have a plan (after this
> is accepted) to remove the `if (&protected3 == protected3b_p ())` part
> and remove `test-xfail-tst-protected1a = yes`)
sounds good. (this can be a separate patch)
> > (although if we reject copy relocs for
> > protected symbols in ld then the test may not work at all)
>
> Right. libc_cv_protected_data in configure.ac should be changed
> to test whether copy relocations on protected data works,
> instead of testing just whether protected data compiles and links.
>
> For aarch64, I plan to make GCC and GNU ld behaviors match clang and gold/ld.lld, the IMO ideal semantics. The full roadmap is
> https://maskray.me/blog/2021-01-09-copy-relocations-canonical-plt-entries-and-protected#summary
this makes sense to me.
> > i think the exe now can interpose a protected symbol in a dso
> > if that uses GOT relocs. (there is no interposition if the
> > linker binds the protected symbol locally of course). i think
> > the commit should mention this change too.
>
> This case (one dso definition copy relocated by exe) does not change.
> Even with the ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA code, the definition in
> the first dso can be interposed if it uses GOT relocs.
>
> The ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA code affects the (multiple dso
> definitions, with the first one copy relocated by exe) case.
either this should be fixed or documented:
on aarch64 this patch vs the extern protected change reverted:
$ elf/ld.so-old --library-path . ./a.out
var in dso: 0xffffa6d50020 2
var in exe: 0x420038 1
$ elf/ld.so-new --library-path . ./a.out
var in dso: 0x420038 1
var in exe: 0x420038 1
$ cat a.c
#include <stdio.h>
void dso_call(void);
int foobar = 1;
int main()
{
dso_call();
printf("var in exe: %p %d\n", &foobar, foobar);
}
$ cat dso.c
#include <stdio.h>
__attribute__((visibility("protected"))) int foobar = 2;
void dso_call(void)
{
printf("var in dso: %p %d\n", &foobar, foobar);
}
$ aarch64-none-linux-gnu-readelf -aW dso.so |grep foobar
000000000001ffd0 0000000800000401 R_AARCH64_GLOB_DAT 0000000000020020 foobar + 0
8: 0000000000020020 4 OBJECT GLOBAL PROTECTED 22 foobar
74: 0000000000020020 4 OBJECT GLOBAL PROTECTED 22 foobar
$ aarch64-none-linux-gnu-readelf -aW a.out |grep foobar
8: 0000000000420038 4 OBJECT GLOBAL DEFAULT 24 foobar
90: 0000000000420038 4 OBJECT GLOBAL DEFAULT 24 foobar
More information about the Libc-alpha
mailing list