-
-
Notifications
You must be signed in to change notification settings - Fork 510
Closed
Labels
Description
Describe the bug
Some shared libraries are corrupted when patchelf sets the RPATH to some new value if they have more than one .shstrtab section.
Steps To Reproduce
Consider this library:
https://www.dropbox.com/s/f4s9g7mxr4fj96v/libcrypt.so.1?dl=0
This library has more than one .shstrtab sections (section 29 and section 33):
❯ readelf -S libcrypt.so.1
There are 34 section headers, starting at offset 0x9258:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .note.gnu.bu[...] NOTE 00000154 000154 000024 00 A 0 0 4
[ 2] .note.ABI-tag NOTE 00000178 000178 000020 00 A 0 0 4
[ 3] .gnu.hash GNU_HASH 00000198 000198 000074 04 A 4 0 4
[ 4] .dynsym DYNSYM 0000020c 00020c 0001e0 10 A 5 1 4
[ 5] .dynstr STRTAB 000003ec 0003ec 00019e 00 A 0 0 1
[ 6] .gnu.version VERSYM 0000058a 00058a 00003c 02 A 4 0 2
[ 7] .gnu.version_d VERDEF 000005c8 0005c8 000038 00 A 5 2 4
[ 8] .gnu.version_r VERNEED 00000600 000600 000050 00 A 5 2 4
[ 9] .rel.dyn REL 00000650 000650 000038 08 A 4 0 4
[10] .rel.plt REL 00000688 000688 0000a0 08 A 4 12 4
[11] .init PROGBITS 00000728 000728 000030 00 AX 0 0 4
[12] .plt PROGBITS 00000758 000758 000150 04 AX 0 0 4
[13] .text PROGBITS 000008b0 0008b0 005168 00 AX 0 0 16
[14] .fini PROGBITS 00005a18 005a18 00001c 00 AX 0 0 4
[15] .rodata PROGBITS 00005a40 005a40 000f40 00 A 0 0 32
[16] .interp PROGBITS 00006980 006980 000013 00 A 0 0 1
[17] .eh_frame_hdr PROGBITS 00006994 006994 0000a4 00 A 0 0 4
[18] .eh_frame PROGBITS 00006a38 006a38 000400 00 A 0 0 4
[19] .hash HASH 00006e38 006e38 000160 04 A 4 0 4
[20] .ctors PROGBITS 00007edc 007edc 000008 00 WA 0 0 4
[21] .dtors PROGBITS 00007ee4 007ee4 000008 00 WA 0 0 4
[22] .jcr PROGBITS 00007eec 007eec 000004 00 WA 0 0 4
[23] .data.rel.ro PROGBITS 00007ef0 007ef0 000004 00 WA 0 0 4
[24] .dynamic DYNAMIC 00007ef4 007ef4 0000e8 08 WA 5 0 4
[25] .got PROGBITS 00007fdc 007fdc 000018 04 WA 0 0 4
[26] .got.plt PROGBITS 00007ff4 007ff4 00005c 04 WA 0 0 4
[27] .bss NOBITS 00008060 008050 0270fc 00 WA 0 0 32
[28] .comment PROGBITS 00000000 008050 00002d 01 MS 0 0 1
[29] .shstrtab STRTAB 00000000 00807d 000196 00 0 0 1
[30] .symtab SYMTAB 00000000 008214 0008e0 10 31 113 4
[31] .strtab STRTAB 00000000 008af4 000622 00 0 0 1
[32] .gnu_debuglink PROGBITS 00000000 009118 00001c 00 0 0 4
[33] .shstrtab STRTAB 00000000 009134 000121 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
when patching the library, for example with
./src/patchelf --set-rpath $ORIGIN --force-rpath libcrypt.so.1
it produces some corruption (look at the section names):
❯ readelf -S libcrypt.so.1
There are 34 section headers, starting at offset 0x9258:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .dyn DYNSYM 0000020c 00020c 0001e0 10 A 30 1 4
[ 2] l.plt VERSYM 0000058a 00058a 00003c 02 A 1 0 2
[ 3] d VERDEF 000005c8 0005c8 000038 00 A 30 2 4
[ 4] _frame_hdr VERNEED 00000600 000600 000050 00 A 30 2 4
[ 5] text REL 00000650 000650 000038 08 A 1 0 4
[ 6] .got.plt REL 00000688 000688 0000a0 08 A 1 8 4
[ 7] PROGBITS 00000728 000728 000030 00 AX 0 0 4
[ 8] .plt PROGBITS 00000758 000758 000150 04 AX 0 0 4
[ 9] anges PROGBITS 000008b0 0008b0 005168 00 AX 0 0 16
[10] d PROGBITS 00005a18 005a18 00001c 00 AX 0 0 4
[11] .symtab PROGBITS 00005a40 005a40 000f40 00 A 0 0 32
[12] terp PROGBITS 00006980 006980 000013 00 A 0 0 1
[13] PROGBITS 00006994 006994 0000a4 00 A 0 0 4
[14] .dynstr PROGBITS 00006a38 006a38 000400 00 A 0 0 4
[15] rsion_d HASH 00006e38 006e38 000160 04 A 1 0 4
[16] ata.rel.ro PROGBITS 00007edc 007edc 000008 00 WA 0 0 4
[17] .ro PROGBITS 00007ee4 007ee4 000008 00 WA 0 0 4
[18] frame PROGBITS 00007eec 007eec 000004 00 WA 0 0 4
[19] i PROGBITS 00007ef0 007ef0 000004 00 WA 0 0 4
[20] ug_aranges PROGBITS 00007fdc 007fdc 000018 04 WA 0 0 4
[21] .bss PROGBITS 00007ff4 007ff4 00005c 04 WA 0 0 4
[22] namic NOBITS 00008060 008050 0270fc 00 WA 0 0 32
[23] ment PROGBITS 00000000 008050 00002d 01 MS 0 0 1
[24] b STRTAB 00000000 00807d 000196 00 0 0 1
[25] .strtab SYMTAB 00000000 008214 0008e0 10 26 113 4
[26] .shstrtab STRTAB 00000000 008af4 000622 00 0 0 1
[27] .version_r PROGBITS 00000000 009118 00001c 00 0 0 4
[28] b STRTAB 00000000 009134 000121 00 0 0 1
[29] u.build-id DYNAMIC 00030000 00a000 0000f0 08 WA 30 0 4
[30] STRTAB 000300f0 00a0f0 0001ac 00 A 0 0 4
[31] u.version_d GNU_HASH 0003029c 00a29c 000074 04 A 1 0 4
[32] nu.version NOTE 00030310 00a310 000020 00 A 0 0 4
[33] NOTE 00030330 00a330 000024 00 A 0 0 4
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
readelf: Error: no .dynamic section in the dynamic segment
Expected behavior
The library is not corrupted and running the previous example works correctly without segfaulting.
patchelf --version output
patchelf 0.12
This may sound like a weird case, but the library provided in this example is taken from a system library in RHEL 6.