|
|
Message-ID: <20260902205500.GX23438@brightrain.aerifal.cx> Date: Wed, 2 Sep 2026 16:55:01 -0400 From: Rich Felker <dalias@...c.org> To: Xusheng Zhi <xusheng142@...il.com> Cc: musl@...ts.openwall.com Subject: Re: [BUG] ldso applies load bias to SHN_ABS symbols during x86_64 R_X86_64_64 relocation On Wed, Sep 02, 2026 at 03:15:28PM -0500, Xusheng Zhi wrote: > Hello, > > I believe musl's dynamic linker applies the load bias to an x86-64 > R_X86_64_64 relocation when the resolved symbol definition is SHN_ABS. > > The expected result for R_X86_64_64 is S + A. For an SHN_ABS symbol, the ELF > gABI says the symbol value is absolute and is not affected by relocation. > The > observed affected behavior is B + S + A, where B is the load base of the DSO > that defines the absolute symbol. > > Minimal reproducer: > > See the attached repro/ directory. > > bash repro/repro.sh > > The reproducer builds: > > * libabs_provider.so, which exports: > abs_sym = 0x12345678 > as an SHN_ABS symbol. > > * main, a freestanding PIE containing one data slot: > .quad abs_sym + 1 > > The PIE exits 0 if the relocated slot equals 0x12345679, otherwise it > exits > 42. > > Observed locally: > > This reproduces with the system musl 1.2.4 loader from Ubuntu's musl > 1.2.4-2 > package and with a local build of the official musl 1.2.6 release tarball. > > glibc loader: 0 > musl 1.2.4 loader: 42 > musl 1.2.6 loader: 42 > > provider symbol: > 0000000012345678 8 OBJECT GLOBAL DEFAULT ABS abs_sym > > main relocation: > R_X86_64_64 abs_sym + 1 > > Expected: > > The relocated slot should be 0x12345679, and the reproducer should exit 0. > > Actual on the affected musl loader: > > The reproducer exits 42 when run through musl's loader. The same binary > exits > 0 with glibc's loader. > > Root-cause pointer: > > On x86-64, R_X86_64_64 uses the symbolic relocation path. In > ldso/dynlink.c, > the resolved symbol value appears to be computed as laddr(def.dso, > def.sym->st_value) for all definitions. That is correct for > section-relative > symbol values, but not for SHN_ABS definitions, where st_value is already > absolute. > > Source pointer and possible minimal fix: > > In the official musl 1.2.6 release: > > arch/x86_64/reloc.h:3: > #define REL_SYMBOLIC R_X86_64_64 > > ldso/dynlink.c:453: > sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0; > > ldso/dynlink.c:467: > case REL_SYMBOLIC: > > ldso/dynlink.c:470: > *reloc_addr = sym_val + addend; > > The smallest relocation-only change matching the reproducer appears to be: > > sym_val = def.sym ? (def.sym->st_shndx == SHN_ABS ? def.sym->st_value : > (size_t)laddr(def.dso, def.sym->st_value)) : 0; > > I am presenting this as a root-cause pointer rather than a fully audited > patch. There is a similar-looking laddr(def.dso, def.sym->st_value) > return in > the dlsym path at ldso/dynlink.c:2289, but the attached reproducer only > covers relocation processing. > > Duplicate search: > > I searched the musl list archive for SHN_ABS/R_X86_64_64/load-bias > reports and > did not find an existing report for this specific case. > > Environment: > > musl tested version: > musl 1.2.6 release, built locally from: > https://musl.libc.org/releases/musl-1.2.6.tar.gz > sha256 > d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a > configure command: > ./configure --prefix=/tmp/verilink-musl-1.2.6.zy4nlJ/install > system musl 1.2.4, Ubuntu package 1.2.4-2, also reproduces > local loaders used: > musl 1.2.6 build: > /tmp/verilink-musl-1.2.6.zy4nlJ/musl-1.2.6/lib/libc.so > system musl 1.2.4: > /lib/ld-musl-x86_64.so.1 -> /lib/x86_64-linux-musl/libc.so > sha256 > 6e8ff8ad02f4a3a0b70029577e2eb9df8f6526aea302a60a8d649874d6fa45ea > binutils version used for preliminary reproducer: > GNU ld 2.42, Ubuntu package 2.42-4ubuntu2.10 > host OS/kernel/architecture: > Ubuntu 24.04.4 LTS > Linux Hihi142-Linux 7.0.0-30-generic x86_64 GNU/Linux > full local output: > repro/build/report-system-musl-1.2.4.txt > repro/build/report-upstream-musl-1.2.6.txt > > I am happy to test a proposed patch or adjust the reproducer if this case is > outside musl's intended dynamic-linker scope. > > If this message is delayed for moderation because I am not subscribed, > please > keep me Cc'd on replies. OK, it looks like the issue is basically that we just don't currently support SHN_ABS. It's not functionality needed for implementing C or other languages I'm aware of, but it is functionality that's intended to be there by the linker, and that's probably useful for certain things. A couple I can think of offhand are: 1. Letting a shared library provide symbols that are not really addresses but rather integer constants, which get patched into the referring module's .data at load time. 2. Letting a shared library define addresses of special fixed-address maps provided by some OS layer (like the ARM kuser_helper page) other than the library. This usage is probably deemed 'unsafe' in a modern setting where ASLR is normal, but it would still make sense in certain embedded/nommu applications. I'm fine with adding this, and it look straightforward and not costly. BTW there was no need for such a verbose report. Just "musl ldso doesn't support SHN_ABS but we'd like it to" would have sufficed. :-) Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.