Subject: A bug in file-dynamic-info used by validate-runpath in gnu-build-system and others.

From: Lukasz Olszewski <[email-masked]>
Date: Sat, 24 Sep 2022 00:28:30 +0200

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.