[PATCH v3] elf: Canonicalize $ORIGIN in an explicit ld.so invocation [BZ 25263]

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Mar 18 12:27:39 GMT 2025



On 18/03/25 08:34, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> When an executable is invoked directly, we calculate $ORIGIN by calling
>> readlink on /proc/self/exe, which the Linux kernel resolves to the
>> target of any symlinks.  However, if an executable is run through ld.so,
>> we cannot use /proc/self/exe and instead use the path given as an
>> argument.  This leads to a different calculation of $ORIGIN, which is
>> most notable in that it causes ldd to behave differently (e.g., by not
>> finding a library) from directly running the program.
>>
>> To make the behavior consistent, take advantage of the fact that the
>> kernel also resolves /proc/self/fd/ symlinks to the target of any
>> symlinks in the same manner, so once we have opened the main executable
>> in order to load it, replace the user-provided path with the result of
>> calling readlink("/proc/self/fd/N").
>>
>> (On non-Linux platforms this resolution does not happen and so no
>> behavior change is needed.)
>>
>> The __fd_to_filename usage on loader (through dl-origin.c) pulls
>> _itoa.c, which in turn defines a lot of
>>
>> The __fd_to_filename requires _fitoa_word and _itoa_word, which for
>> 32-bits pulls a lot of definitions from _itoa.c (due _ITOA_NEEDED
>> debing defined).  To simplify the build move the required function
>> to a new file, _fitoa_word.c.
>>
>> Checked on x86_64-linux-gnu and i686-linux-gnu.
>>
>> Co-authored-by: Geoffrey Thomas <geofft@ldpreload.com>
> 
> This
> 
> or
> 
> commit 997f49fbadf892136c77115edd537c832fb8074d
> Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Date:   Mon Mar 17 19:08:22 2025 +0000
> 
>     elf: Fix tst-origin make rules
>     
>     Add tests-special before include Rules and compile liborigin.os with
>     MODULE_NAME set to testsuite instead of libc.
> 
> caused:
> 
> /usr/bin/ld: /home/fweimer/src/gnu/glibc/build/libc.so: undefined reference to `__tunable_is_initialized@GLIBC_PRIVATE'
> 
> Failing the “make check” build.  I think this happens because the linker
> invocation links against system ld.so.
> 
> Is there a reason why we can't use the usual test DSO linker invocation?

The only requirement is to avoid a the liborigin.so without a full path,
which is the default for --enable-hardcoded-path-in-tests. I also tried
to mimic the original provided testcase and avoid the extra RPATH entries,
it is not really required.

I only tested on system with recent glibc, so I think that's why I have
not see the this build issue. Does the following fix the build issue?

diff --git a/elf/Makefile b/elf/Makefile
index 5a50c7d50c..3d60000ec9 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -456,6 +456,7 @@ tests += \
   tst-noload \
   tst-non-directory-path \
   tst-null-argv \
+  tst-origin \
   tst-p_align1 \
   tst-p_align2 \
   tst-p_align3 \
@@ -1195,7 +1196,6 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
 # filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
 # rules.
 modules-names-nobuild += \
-  liborigin-mod \
   filtmod1 \
   tst-audit24bmod1 \
   tst-audit24bmod2 \
@@ -3451,15 +3451,8 @@ $(objpfx)tst-dlopen-constructor-null-mod2.so: \

 CFLAGS-tst-origin.c += $(no-stack-protector)
 CFLAGS-liborigin-mod.c += $(no-stack-protector)
-$(objpfx)tst-origin: $(objpfx)tst-origin.o $(objpfx)liborigin-mod.so
-       $(LINK.o) -o $@ -B$(csu-objpfx) $(LDFLAGS.so) $< \
-               -Wl,-rpath,\$$ORIGIN \
-               -L$(subst :, -L,$(rpath-link)) -Wl,--no-as-needed -lorigin-mod
-$(objpfx)liborigin-mod.so: $(objpfx)liborigin-mod.os
-       $(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \
-               $(LDFLAGS-soname-fname) \
-               $<
-$(objpfx)tst-origin.out: tst-origin.sh $(objpfx)tst-origin
+LDFLAGS-tst-origin += -Wl,-rpath,\$$ORIGIN -L$(subst :, -L,$(rpath-link)) -lorigin-mod
+$(objpfx)tst-origin.out: tst-origin.sh $(objpfx)liborigin-mod.so $(objpfx)tst-origin
        $(SHELL) \
                $< \
                '$(common-objpfx)' \




More information about the Libc-alpha mailing list