Summary: | Copy relocation leads to change in read-only data | ||
---|---|---|---|
Product: | binutils | Reporter: | H.J. Lu <hjl.tools> |
Component: | ld | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | normal | CC: | amodra |
Priority: | P2 | ||
Version: | 2.27 | ||
Target Milestone: | 2.28 | ||
Host: | Target: | x86 | |
Build: | Last reconfirmed: |
Description
H.J. Lu
2016-04-18 16:37:31 UTC
And how is that a bug? The program invokes undefined behavior. (In reply to Andreas Schwab from comment #1) > And how is that a bug? The program invokes undefined behavior. Linker should generate copy relocation against read-only symbol in .data.rel.ro section, instead of .bss section, so that the copy of read-only symbol is also read-only after relocation at run-time. Here's a testcase that I think does not invoke any undefined behaviour, and shows various inconsistencies with protected variables and copy relocs. Depending on the version of gcc (and glibc!) you may see &x != x or no segfault. Compile protmain with -fPIC to see correct behaviour. cat > prot.h <<\EOF extern void *x; extern void aprint (void); extern void boom (void); EOF cat > prota.c <<\EOF #include "prot.h" void __attribute__ ((visibility ("protected"), section(".data.rel.ro"))) *x = &x; void aprint (void) { __builtin_printf ("A: &x = %p, x = %p\n", &x, x); } EOF cat > protb.c <<\EOF #include "prot.h" void boom (void) { x = 0; } EOF cat > protmain.c <<\EOF #include "prot.h" int main (void) { __builtin_printf ("main: &x = %p, x = %p\n", &x, x); aprint (); boom (); return 0; } EOF gcc -O2 -fPIC -shared -o liba.so prota.c protb.c -Wl,-z,relro gcc -O2 -o protmain protmain.c -L. -la -Wl,-rpath,. ./protmain BTW, the testcase in comment #3 (and yours too!) show just how difficult it is to fix this problem. When the main program is *not* relro you don't have anywhere to put the new .dynbss.ro or whatever you want to call the internal linker generated section for read-only .dynbss variables. You don't have a .data.rel.ro in the main executable and can't tack them on to .rodata, because then ld.so will segfault when applying the copy relocation.. |