Closed JonathonReinhart closed 1 year ago
The problem is missing symlinks:
In ubuntu 22:04, there is no libnss_files.so
symlink 😦
jreinhart@cbc4e6bb2b96:~/gitrepos/staticx$ ls -l /usr/lib/x86_64-linux-gnu/libnss*
lrwxrwxrwx 1 root root 40 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_compat.so -> /lib/x86_64-linux-gnu/libnss_compat.so.2
-rw-r--r-- 1 root root 44024 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_compat.so.2
-rw-r--r-- 1 root root 14352 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_dns.so.2
-rw-r--r-- 1 root root 14352 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_files.so.2
lrwxrwxrwx 1 root root 40 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_hesiod.so -> /lib/x86_64-linux-gnu/libnss_hesiod.so.2
-rw-r--r-- 1 root root 27160 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_hesiod.so.2
Note that there is no libnss_dns.so
or libnss_files.so
symlink. Hmm.
It's also a little suspicious that both libnss_dns.so.2
and libnss_files.so.2
are exactly the same size:
-rw-r--r-- 1 root root 14352 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_dns.so.2
-rw-r--r-- 1 root root 14352 Jul 6 2022 /usr/lib/x86_64-linux-gnu/libnss_files.so.2
As I suspected, it appears that libnss_dns.so.2
and libnss_files.so.2
are stubs (export no symbols). The real implementation is moved into libc as of GLIBC 2.34.
Relevant changes:
libnss_files
glibc-2.33.9000-881-g9ed48feed8
): nss: Do not install static linker input files for libnss_files
nss: Access nss_files through direct references
nss_files: Move into libc
libnss_dns
nss: Directly load nss_dns, without going through dlsym/dlopen
resolv: Move nss_dns into libc
If libnss_files
/libnss_dns
are built into libc, we can just leave these out of the link.
How do we detect this?
libnss_files
(_dns
)
Reopening as #255 is incomplete. See https://github.com/JonathonReinhart/staticx/pull/255#issuecomment-1630120893.
It needs to provide runtime libnssfix detection, not just build-time.
I'm yanking staticx 0.14.0 from PyPI, because what's there (libnssfix.so
not linking against libnss_files
, causing dlopen of system lib) is arguably worse (odd app runtime behavior / crash) than 0.13.9 (which works on glibc>=2.34 because libnssfix.so
has NEEDED
of the soname libnss_files.so.2
), so the dependencies are picked up.
We just can't build staticx on glibc>=2.34 (as the title ostensibly states).
My initial thought was:
It needs to provide runtime libnssfix detection, not just build-time.
Meaning, when staticx
is run, it needs to determine if the glibc (against which the given app was linked) has nss_files and nss_dns builtin -- not the GLIBC used to build staticx.
libnssfix.so
which does not link against libnss_files
/libnss_dns
.libnssfix.so
which does link against them (and they will be bundled).But based on my test (staticx 0.13.9 works on ubuntu 22.04):
$ ldd /usr/local/lib/python3.10/dist-packages/staticx/assets/release/libnssfix.so
linux-vdso.so.1 (0x00007ffec95a9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f982aa84000)
libnss_files.so.2 => /lib/x86_64-linux-gnu/libnss_files.so.2 (0x00007f982aa7f000)
libnss_dns.so.2 => /lib/x86_64-linux-gnu/libnss_dns.so.2 (0x00007f982aa7a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f982acb6000)
the stubs are present and don't hurt anything.
We just need to get the NEEDED tags on libnssfix.so
with the SONAME (including .2
), like they always were:
$ readelf --dynamic /usr/local/lib/python3.10/dist-packages/staticx/assets/release/libnssfix.so | grep '(NEEDED)'
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [libnss_files.so.2]
0x0000000000000001 (NEEDED) Shared library: [libnss_dns.so.2]
How do we best achieve this in our scons build system? (Keep in mind that -lnss_files
does not work because of the missing symlinks).
Ideas:
Noted here: https://github.com/JonathonReinhart/staticx/pull/194#issuecomment-1624289769