The relative RPATH ("./") supplied to linker options in CFLAGS is resolved relative to current working directory and not the executable directory, which will lead in incorrect resolution when the test executables are run from elsewhere. Changing it to $ORIGIN makes it resolve relative to the directory in which the executables reside, which is supposedly the desired behaviour. This patch also moves these CFLAGS to lib.mk, so the RPATH is provided for all selftest binaries, which is arguably a useful default.
Comparison of
find -type f -perm /111 -print0 | sort -z | xargs -0 ldd 2>&1 | sed 's/([^)]*)//'
output before and after the change shows that only the binaries that previously used RPATH of "," are affected and that the linker now able to find the used dynamic libraries when the executable invoked outside directory it resides in:
$ diff -U 0 old_ldd new_ldd --- old_ldd 2024-08-12 08:00:16.093535910 -0400 +++ new_ldd 2024-08-09 09:58:22.657883491 -0400 @@ -10 +10 @@ - libatest.so => not found + libatest.so => /home/build/linux/tools/testing/selftests/./alsa/libatest.so @@ -17 +17 @@ - libatest.so => not found + libatest.so => /home/build/linux/tools/testing/selftests/./alsa/libatest.so @@ -24 +24 @@ - libatest.so => not found + libatest.so => /home/build/linux/tools/testing/selftests/./alsa/libatest.so @@ -119 +119 @@ - liburandom_read.so => not found + liburandom_read.so => /home/build/linux/tools/testing/selftests/./bpf/no_alu32/liburandom_read.so @@ -445 +445 @@ - liburandom_read.so => not found + liburandom_read.so => /home/build/linux/tools/testing/selftests/./bpf/liburandom_read.so @@ -3321 +3321 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3326 +3326 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3331 +3331 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3340 +3340 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3345 +3345 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3350 +3350 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3355 +3355 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3360 +3360 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so @@ -3365 +3365 @@ - librseq.so => not found + librseq.so => /home/build/linux/tools/testing/selftests/./rseq/librseq.so
Some minimal testing is done to verify that it does not affect the tests: alsa, rseq, and sched (which also had the RPATH tag but didn't actually link against any locally built libraries) selftests are run successfully before and after the change; for the rest of the selftests, there was no regression observed as well.
Discovered by the check-rpaths script[1][2] that checks for insecure RPATH/RUNPATH[3], such as relative directories, during an attempt to package BPF selftests for later use in CI:
ERROR 0004: file '/usr/libexec/kselftests/bpf/urandom_read' contains an insecure runpath '.' in [.]
[1] https://github.com/rpm-software-management/rpm/blob/master/scripts/check-rpa... [2] https://github.com/rpm-software-management/rpm/blob/master/scripts/check-rpa... [3] https://cwe.mitre.org/data/definitions/426.html
Signed-off-by: Eugene Syromiatnikov esyr@redhat.com --- v2: - Consolidated the updated -L/-Wl,-rpath setting into lib.mk - Described the testing done in the commit message v1: https://lore.kernel.org/lkml/20240808145639.GA20510@asgard.redhat.com/ https://lore.kernel.org/lkml/20240808151335.GA5495@asgard.redhat.com/ https://lore.kernel.org/lkml/20240808151621.GA10025@asgard.redhat.com/ https://lore.kernel.org/lkml/20240808151621.GA10025@asgard.redhat.com/ --- tools/testing/selftests/alsa/Makefile | 1 - tools/testing/selftests/bpf/Makefile | 5 ++--- tools/testing/selftests/lib.mk | 3 +++ tools/testing/selftests/rseq/Makefile | 2 +- tools/testing/selftests/sched/Makefile | 3 +-- 5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/alsa/Makefile b/tools/testing/selftests/alsa/Makefile index c1ce39874e2b..68a1651360e5 100644 --- a/tools/testing/selftests/alsa/Makefile +++ b/tools/testing/selftests/alsa/Makefile @@ -6,7 +6,6 @@ LDLIBS += $(shell pkg-config --libs alsa) ifeq ($(LDLIBS),) LDLIBS += -lasound endif -CFLAGS += -L$(OUTPUT) -Wl,-rpath=./
LDLIBS+=-lpthread
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 81d4757ecd4c..a152c12b8a3b 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -239,9 +239,8 @@ $(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_r $(call msg,BINARY,,$@) $(Q)$(CLANG) $(CLANG_TARGET_ARCH) \ $(filter-out -static,$(CFLAGS) $(LDFLAGS)) $(filter %.c,$^) \ - -lurandom_read $(filter-out -static,$(LDLIBS)) -L$(OUTPUT) \ - -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 \ - -Wl,-rpath=. -o $@ + -lurandom_read $(filter-out -static,$(LDLIBS)) \ + -fuse-ld=$(LLD) -Wl,-znoseparate-code -Wl,--build-id=sha1 -o $@
$(OUTPUT)/sign-file: ../../../../scripts/sign-file.c $(call msg,SIGN-FILE,,$@) diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index d6edcfcb5be8..d75a20bb569c 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -199,6 +199,9 @@ clean: $(if $(TEST_GEN_MODS_DIR),clean_mods_dir) # Build with _GNU_SOURCE by default CFLAGS += -D_GNU_SOURCE=
+# Simplify usage of libraries built alongside the test executables +CFLAGS += -L$(OUTPUT) -Wl,-rpath=$$ORIGIN/ + # Enables to extend CFLAGS and LDFLAGS from command line, e.g. # make USERCFLAGS=-Werror USERLDFLAGS=-static CFLAGS += $(USERCFLAGS) diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile index 5a3432fceb58..887b45d4a675 100644 --- a/tools/testing/selftests/rseq/Makefile +++ b/tools/testing/selftests/rseq/Makefile @@ -6,7 +6,7 @@ endif
top_srcdir = ../../../..
-CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) -L$(OUTPUT) -Wl,-rpath=./ \ +CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) \ $(CLANG_FLAGS) -I$(top_srcdir)/tools/include LDLIBS += -lpthread -ldl
diff --git a/tools/testing/selftests/sched/Makefile b/tools/testing/selftests/sched/Makefile index 099ee9213557..0e4581ded9d6 100644 --- a/tools/testing/selftests/sched/Makefile +++ b/tools/testing/selftests/sched/Makefile @@ -4,8 +4,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) CLANG_FLAGS += -no-integrated-as endif
-CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) -Wl,-rpath=./ \ - $(CLANG_FLAGS) +CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) $(CLANG_FLAGS) LDLIBS += -lpthread
TEST_GEN_FILES := cs_prctl_test