aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-08-13 18:25:52 -0700
committerAndrew G. Morgan <morgan@kernel.org>2021-08-13 20:43:14 -0700
commitd5daba542ae15cf47752ab5430ded4cd0d0a7ce3 (patch)
tree0b35d806c41f24ad9d58962ae4c4bbba10d50b04
parent6dea1813f269f9c03cea226fffdd75670c70ea01 (diff)
downloadlibcap-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/.gitignore2
-rw-r--r--pam_cap/Makefile29
-rw-r--r--pam_cap/lazylink.c20
-rw-r--r--progs/Makefile8
-rw-r--r--tests/Makefile16
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