Hello, I find out strip (version 2.7 and up to the latest git commit) produces 
incorrect elf for a shared library called libpython3.so​ in this python build 
standalone project (one example is 
https://github.com/indygreg/python-build-standalone/releases/tag/20210506).

I tested the python3.8.10 and python3.9.5 from the prebuilt assets:

(make sure you have zstd installed)
$ wget 
https://github.com/indygreg/python-build-standalone/releases/download/20210506/cpython-3.8.10-x86_64-unknown-linux-gnu-pgo-20210506T0943.tar.zst
 && tar xf cpython-3.8.10-x86_64-unknown-linux-gnu-pgo-20210506T0943.tar.zs

$ strip --verbose python/install/lib/libpython3.so
copy from `python/install/lib/libpython3.so' [elf64-x86-64] to 
`python/install/lib/stdefEcz' [elf64-x86-64]
strip: python/install/lib/stdefEcz: section .dynamic lma 0x51c0 adjusted to 
0x61a0
strip: python/install/lib/stdefEcz: section .dynstr lma 0x53a0 adjusted to 
0x6380

$ ldd python/install/lib/libpython3.so
        linux-vdso.so.1 (0x00007fffa5118000)
        libpython3.8.so.1.0 => 
/home/junsong-li/playground/download/python/install/lib/../lib/libpython3.8.so.1.0
 (0x00007ff8825c4000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 
(0x00007ff882598000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff8823a6000)
        libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 
(0x00007ff88236b000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff882365000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff882359000)
        libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007ff882354000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff882205000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff883993000)

$ strip --verbose python/install/lib/libpython3.so
copy from `python/install/lib/libpython3.so' [elf64-x86-64] to 
`python/install/lib/st51yoNs' [elf64-x86-64]

$ ldd python/install/lib/libpython3.so
        statically linked

I took a quick investigation on the produced elf: the .dynamic section is moved 
to 0x61a0 only when I run the second strip but the adjustment is reported 
during the first run. Here is the readelf output diff of the first strip result 
and the second strip result

$ diff /tmp/v2.txt /tmp/v3.txt
13c13
<   Start of section headers:          17688 (bytes into file)
---
>   Start of section headers:          25848 (bytes into file)
61c61
<   [18] .bss              NOBITS           0000000000004020  00003020
---
>   [18] .bss              NOBITS           0000000000004020  00004020
63c63
<   [19] .comment          PROGBITS         0000000000000000  00004458
---
>   [19] .comment          PROGBITS         0000000000000000  00006438
65c65
<   [20] .dynamic          DYNAMIC          00000000000051c0  000041c0
---
>   [20] .dynamic          DYNAMIC          00000000000051c0  000061a0
67c67
<   [21] .dynstr           STRTAB           00000000000053a0  000043a0
---
>   [21] .dynstr           STRTAB           00000000000053a0  00006380
69c69
<   [22] .shstrtab         STRTAB           0000000000000000  0000446a
---
>   [22] .shstrtab         STRTAB           0000000000000000  0000644a
94,96c94,96
<   LOAD           0x0000000000003020 0x0000000000004020 0x0000000000005000
<                  0x0000000000001438 0x0000000000001438  RW     0x1000
<   DYNAMIC        0x00000000000041c0 0x00000000000051c0 0x00000000000051c0
---
>   LOAD           0x0000000000003020 0x0000000000003020 0x0000000000003020
>                  0x0000000000003418 0x0000000000003418  RW     0x1000
>   DYNAMIC        0x00000000000061a0 0x00000000000051c0 0x00000000000061a0
110c110
< Dynamic section at offset 0x41c0 contains 26 entries:
---
> Dynamic section at offset 0x61a0 contains 26 entries:


Note after the first strip, the dynamic section is still at 0x41c0 even if 
strip reported it has adjusted this section to 0x61a0.

In older versions (I happen to have a strip 2.26.1), strip reports errors, 
which prevents the binary corruption:

$ strip --verbose libpython3.so
copy from `libpython3.so' [elf64-x86-64] to `stT8vsRX' [elf64-x86-64]
strip: stT8vsRX: Not enough room for program headers, try linking with -N
strip:stT8vsRX[.hash]: Bad value

Reply via email to