A bug in file-dynamic-info used by validate-runpath in gnu-build-system and others.
(address . bug-guix@gnu.org)
It appears I found a bug in guix triggered by certain binary data
present in an ELF header.
While running a validate runpath phase of a build-system for a new
package that is not a part of guix I encountered unusual errors
reported for certain binary files. Those binary files RUNPATHs were
modified by patchelf by adding a colon character followed by a
/gnu/store directory folder to runpath. As far as readelf/patchelf and
ld are concerned the binary files appear to contain a valid elf header
with valid DT_DYNAMIC section.
However, something in the ELF header triggers a bug in Guix's
file-runpath / file-dynamic-info procedure that result in the
following output:
scheme@(guix-user)> (file-dynamic-info
"/gnu/store/20z595j5jas5ri3nrza5465gbxwf9kmf-python-redacted/lib/python3.9/site-packages/torch/bin/FileStoreTest")
$13 = #<<elf-dynamic-info> soname: #f needed: ("" "" "" "" "" "" "" ""
"" "" "" "" "" "" "") rpath: () runpath: ()>
scheme@(guix-user)>
As can be seen above file-dynamic-info is unable to read the NEEDED
items, but correctly reports 8 of them. Additionally it is unable to
read the RUNPATH variable and returns an empty string. All those
values are populated in the header as shown below.
readelf -d reports the following correct DT_DYNAMIC:
[luk@archczop guix]$ readelf -d
/gnu/store/20z595j5jas5ri3nrza5465gbxwf9kmf-python-redacted/lib/python3.9/site-packages/torch/bin/FileStoreTest
Dynamic section at offset 0xfcf0 contains 40 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtorch_cpu.so]
0x0000000000000001 (NEEDED) Shared library:
[libgtest_main.so.1.11.0]
0x0000000000000001 (NEEDED) Shared library: [libgtest.so.1.11.0]
0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0]
0x0000000000000001 (NEEDED) Shared library: [libprotobuf.so.28]
0x0000000000000001 (NEEDED) Shared library: [libc10.so]
0x0000000000000001 (NEEDED) Shared library:
[libmkl_intel_lp64.so.2]
0x0000000000000001 (NEEDED) Shared library:
[libmkl_gnu_thread.so.2]
0x0000000000000001 (NEEDED) Shared library: [libmkl_core.so.2]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgomp.so.1]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000001d (RUNPATH) Library runpath:
[$ORIGIN/../lib:/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33/lib:/gnu/store/094bbaq6glba86h1d4cj16xhdi6fk2jl-gcc-10.3.0-lib/lib:/gnu/store/mbzav28sik3zr3kbw1jyh4qk3zmkh6xn-googletest-1.11.0/lib:/gnu/store/9pyydl5w9xnz1qm56sxn1zh4qny6fkxz-protobuf-3.17.3/lib:/gnu/store/fj5npv9kpsiihrzpzhdlcz5q6bax15s8-mkl-2022.1.0/lib:/gnu/store/094bbaq6glba86h1d4cj16xhdi6fk2jl-gcc-10.3.0-lib/lib/gcc/x86_64-unknown-linux-gnu/10.3.0/../../..:/gnu/store/janq8zcngwc7120gyj41cc2yysk7p9i5-nvidia-libs-515.65.01/lib]
0x000000000000000c (INIT) 0x405000
0x000000000000000d (FINI) 0x40bed4
0x0000000000000019 (INIT_ARRAY) 0x40f6c8
0x000000000000001b (INIT_ARRAYSZ) 16 (bytes)
0x000000000000001a (FINI_ARRAY) 0x40f6d8
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x402210
0x000000006ffffef5 (GNU_HASH) 0x401fa8
0x0000000000000005 (STRTAB) 0x3ff350
0x0000000000000006 (SYMTAB) 0x4011b0
0x000000000000000a (STRSZ) 7769 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x410000
0x0000000000000002 (PLTRELSZ) 1680 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x4039e0
0x0000000000000007 (RELA) 0x403710
0x0000000000000008 (RELASZ) 720 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x403620
0x000000006fffffff (VERNEEDNUM) 4
0x000000006ffffff0 (VERSYM) 0x4034f0
0x0000000000000000 (NULL) 0x0
Therefore deeper analysis of what is in the binary header that
triggers the bug is required. I have a number of those binary files. I
attached the smallest one(74kB) base64 encoded to this email. It is
the binary named FileStoreTest used in the report above. If it gets
stripped from the message I'll reply by submitting it in the body of
the message.