diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2021-08-13 18:25:52 -0700 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2021-08-13 20:43:14 -0700 |
commit | d5daba542ae15cf47752ab5430ded4cd0d0a7ce3 (patch) | |
tree | 0b35d806c41f24ad9d58962ae4c4bbba10d50b04 | |
parent | 6dea1813f269f9c03cea226fffdd75670c70ea01 (diff) | |
download | libcap2-d5daba542ae15cf47752ab5430ded4cd0d0a7ce3.tar.gz |
Support distributions that build libcap with aggressive link options.
Discussion of one such setup in this bug (reported by David Runge):
https://bugzilla.kernel.org/show_bug.cgi?id=214023
Work around the failure to run ./pam_cap.so in these cases with
some more Makefile magic, and adjust test building with these
flags so it works in DYNAMIC=yes|no and SHARED=yes|no cases.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | pam_cap/.gitignore | 2 | ||||
-rw-r--r-- | pam_cap/Makefile | 29 | ||||
-rw-r--r-- | pam_cap/lazylink.c | 20 | ||||
-rw-r--r-- | progs/Makefile | 8 | ||||
-rw-r--r-- | tests/Makefile | 16 |
5 files changed, 54 insertions, 21 deletions
diff --git a/pam_cap/.gitignore b/pam_cap/.gitignore index 05e9bbf..ef9e57f 100644 --- a/pam_cap/.gitignore +++ b/pam_cap/.gitignore @@ -1,3 +1,5 @@ pam_cap.so testlink test_pam_cap +lazylink.so +pam_cap_linkopts diff --git a/pam_cap/Makefile b/pam_cap/Makefile index cb0b813..689239e 100644 --- a/pam_cap/Makefile +++ b/pam_cap/Makefile @@ -16,16 +16,27 @@ install: all execable.o: execable.c ../libcap/execable.h ../libcap/loader.txt $(CC) $(CFLAGS) $(IPATH) -DLIBCAP_VERSION=\"libcap-$(VERSION).$(MINOR)\" -DSHARED_LOADER=\"$(shell cat ../libcap/loader.txt)\" -c execable.c -o $@ -# Note (as the author of much of the Linux-PAM library, I am confident -# that this next line does *not* require -lpam on it.) If you think it -# does, *verify that it does*, and if you observe that it fails as -# written (and you know why it fails), email me and explain why. Thanks! +pam_cap.so: pam_cap.o execable.o pam_cap_linkopts + cat pam_cap_linkopts | xargs -e $(LD) -o $@ pam_cap.o execable.o $(LIBCAPLIB) $(LDFLAGS) + +# Some distributions force link everything at compile time, and don't +# take advantage of libpam's dlopen runtime options to resolve ill +# defined symbols from its own linkage as needed. (As the original +# author of that part of libpam, I consider this force linking +# premature optimization.) We debugged its consequences to pam_cap.so +# as part of: +# +# https://bugzilla.kernel.org/show_bug.cgi?id=214023 # -# This bug documents some overriden CC and LD flags that cause it to -# be necessary: https://bugzilla.kernel.org/show_bug.cgi?id=214023 +# If the current build environment is one of those, extend the link +# options for pam_cap.so to force linkage against libpam and the +# gazillion other things libpam is linked against... +pam_cap_linkopts: lazylink.so + echo "-Wl,-e,__so_start" > $@ + ./lazylink.so || echo "-lpam" >> $@ -pam_cap.so: pam_cap.o execable.o - $(LD) -o pam_cap.so $+ $(LIBCAPLIB) $(LDFLAGS) -Wl,-e,__so_start +lazylink.so: lazylink.c ../libcap/execable.h ../libcap/loader.txt + $(LD) -o $@ $(CFLAGS) $(IPATH) lazylink.c -DSHARED_LOADER=\"$(shell cat ../libcap/loader.txt)\" $(LDFLAGS) -Wl,-e,__so_start pam_cap.o: pam_cap.c $(CC) $(CFLAGS) $(IPATH) -c $< -o $@ @@ -56,4 +67,4 @@ sudotest: test test_pam_cap sudo ./test_pam_cap delta 0x41 0x80 0x41 config=./sudotest.conf clean: - rm -f *.o *.so testlink test_pam_cap *~ + rm -f *.o *.so testlink lazylink.so test_pam_cap pam_cap_linkopts *~ diff --git a/pam_cap/lazylink.c b/pam_cap/lazylink.c new file mode 100644 index 0000000..969c92d --- /dev/null +++ b/pam_cap/lazylink.c @@ -0,0 +1,20 @@ +/* + * Test if the provided LDFLAGS support lazy linking + */ +#include <stdio.h> +#include <stdlib.h> + +#include "../libcap/execable.h" + +extern int nothing_sets_this(void); +extern void nothing_uses_this(void); + +void nothing_uses_this(void) +{ + nothing_sets_this(); +} + +SO_MAIN(int argc, char **argv) +{ + exit(0); +} diff --git a/progs/Makefile b/progs/Makefile index 3e82862..2c3c993 100644 --- a/progs/Makefile +++ b/progs/Makefile @@ -14,7 +14,7 @@ ifeq ($(DYNAMIC),yes) LDPATH = LD_LIBRARY_PATH=../libcap DEPS = ../libcap/libcap.so else -LDFLAGS += --static +LDSTATIC = --static DEPS = ../libcap/libcap.a endif @@ -25,7 +25,7 @@ endif make -C ../libcap libcap.so $(BUILD): %: %.o $(DEPS) - $(CC) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDFLAGS) + $(CC) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDSTATIC) %.o: %.c $(INCS) $(CC) $(IPATH) $(CFLAGS) -c $< -o $@ @@ -46,10 +46,10 @@ capshdoc.h.cf: capshdoc.h ./mkcapshdoc.sh diff -u capshdoc.h $@ || (rm $@ ; exit 1) capsh: capsh.c capshdoc.h.cf $(DEPS) - $(CC) $(IPATH) $(CAPSH_SHELL) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDFLAGS) + $(CC) $(IPATH) $(CAPSH_SHELL) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDSTATIC) tcapsh-static: capsh.c capshdoc.h.cf $(DEPS) - $(CC) $(IPATH) $(CAPSH_SHELL) $(CFLAGS) -o $@ $< $(LIBCAPLIB) $(LDFLAGS) --static + $(CC) $(IPATH) $(CAPSH_SHELL) $(CFLAGS) -o $@ $< $(LIBCAPLIB) --static uns_test: ../tests/uns_test.c $(MAKE) -C ../tests uns_test diff --git a/tests/Makefile b/tests/Makefile index 3a917c4..7ce8776 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -22,7 +22,7 @@ ifeq ($(PTHREADS),yes) DEPS += ../libcap/libpsx.so endif else -LDFLAGS += --static +LDSTATIC = --static DEPS=../libcap/libcap.a ifeq ($(PTHREADS),yes) DEPS += ../libcap/libpsx.a @@ -63,17 +63,17 @@ run_psx_test: psx_test ./psx_test psx_test: psx_test.c $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBPSXLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBPSXLIB) $(LDSTATIC) run_libcap_psx_test: libcap_psx_test ./libcap_psx_test libcap_psx_test: libcap_psx_test.c $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LIBPSXLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LIBPSXLIB) $(LDSTATIC) # privileged uns_test: uns_test.c $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LDSTATIC) run_uns_test: uns_test echo exit | sudo ./uns_test @@ -85,13 +85,13 @@ run_libcap_psx_launch_test: libcap_psx_launch_test ../progs/tcapsh-static sudo ./libcap_psx_launch_test libcap_launch_test: libcap_launch_test.c $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LDSTATIC) # This varies only slightly from the above insofar as it currently # only links in the pthreads fork support. TODO() we need to change # the source to do something interesting with pthreads. libcap_psx_launch_test: libcap_launch_test.c $(DEPS) - $(CC) $(CFLAGS) $(IPATH) -DWITH_PTHREADS $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LIBPSXLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) -DWITH_PTHREADS $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LIBPSXLIB) $(LDSTATIC) # This test demonstrates that libpsx is needed to secure multithreaded @@ -106,12 +106,12 @@ exploit.o: exploit.c $(CC) $(CFLAGS) $(IPATH) -c $< exploit: exploit.o $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) -lpthread $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) -lpthread $(LDSTATIC) # Note, for some reason, the order of libraries is important to avoid # the exploit working for dynamic linking. noexploit: exploit.o $(DEPS) - $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBPSXLIB) $(LIBCAPLIB) $(LDFLAGS) + $(CC) $(CFLAGS) $(IPATH) $< -o $@ $(LINKEXTRA) $(LIBPSXLIB) $(LIBCAPLIB) $(LDSTATIC) # This one runs in a chroot with no shared library files. noop: noop.c |