Bug 219456 - libpsx and libcap requires -wrap'ing of pthread_create()
Summary: libpsx and libcap requires -wrap'ing of pthread_create()
Status: RESOLVED CODE_FIX
Alias: None
Product: Tools
Classification: Unclassified
Component: libcap (show other bugs)
Hardware: All Linux
: P3 enhancement
Assignee: Andrew G. Morgan
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-11-02 01:38 UTC by Andrew G. Morgan
Modified: 2024-11-14 04:21 UTC (History)
1 user (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Andrew G. Morgan 2024-11-02 01:38:50 UTC
I'm filing this bug to find a different way to transparently reconfigure libcap to use the libpsx functions when a binary is linked with both -lcap and -lpsx. The intention being that this linking arrangement causes libcap to operate with a shared security context over the process.

Today, libcap recognizes that libpsx has been linked by calling psx_load_syscall() at library initialization time. Inside libcap, this function is actually defined as 

   __attribute__((weak))
   psx_load_syscall(...)

and the same function is defined in libpsx, but not with a weak attribute. So, if libpsx is linked into the application, libpsx's version dominates that of libcap. This combines to cause the libpsx version to provide the needed functions when libcap:cap_set_syscall() calls it.

In libcap-2.71 and earlier, libpsx could be forced to be linked because it was the library that provided the only definition of __real_pthread_create() and the linkage instructions for -lpsx were:

   -wrap,pthread_create -lpsx

which required __real_thread_create() to exist somewhere in the linked binary.

With libpsx-2.72 (not yet released) we've rewritten libpsx to not implement its functionality with respect to the pthread abstraction, but against Linux's native thread implementation. As such, the only remaining reason for the wrapping is to force libpsx to be linked against the binary.

So, strictly speaking, the pthread_create() function is no longer important to libpsx use. However, I've not yet found an alternate way to force libpsx.a or libpsx.so to actually link in the quiet libcap linking mode I want. So, I've had to retain the -wrap stuff with what will become libcap-2.72.

This bug is to find a better way to silently help libcap recognize it has been linked to a binary with libpsx, and to force -lpsx to actually link against a binary when nothing in that binary calls libpsx functions.
Comment 2 Andrew G. Morgan 2024-11-09 14:50:36 UTC
This seems to explain what I see with the static link:

https://stackoverflow.com/a/37191811/14760867

Namely, with

--- a/Make.Rules
+++ b/Make.Rules
@@ -107,7 +107,7 @@ endif
 USE_GPERF ?= $(shell which gperf >/dev/null 2>/dev/null && echo yes)
 
 LIBCAPLIB := -L$(topdir)/libcap -lcap
-PSXLINKFLAGS :=  -lpthread -Wl,-wrap,pthread_create
+PSXLINKFLAGS :=  -lpthread
 LIBPSXLIB := -L$(topdir)/libcap -lpsx $(PSXLINKFLAGS)
 
 INCS=$(topdir)/libcap/include/sys/capability.h

$ make clean all test sudotest
[...]
sudo ./noexploit ; if [ $? -eq 0 ]; then exit 0; else exit 1 ; fi
program starting
started privileged thread
dropping privilege from main process thread
no privilege in main process thread: len:1, caps:"="
greatest privilege in main process thread: len:3, caps:"=ep"
exploit succeeded

So, without the wrapping the exploit succeeds. The reason appears to be that nothing is forcing the linking of libpsx.a in this static link case. If I manually run:

$ cd tests
$ gcc -O2  -Wall -Wwrite-strings -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wshadow -Wunreachable-code --static exploit.o -o noexploit  -L/home/andrew/gits/libcap/tests/../libcap -lcap -Wl,--whole-archive -lpsx -Wl,--no-whole-archive -lpthread
$ sudo ./noexploit 
program starting
started privileged thread
dropping privilege from main process thread
no privilege in main process thread: len:1, caps:"="
greatest privilege in main process thread: len:1, caps:"="
exploit failed

Evidently the `-Wl,--whole-archive -lpsx -Wl,--no-whole-archive` flags seem to force the linking I want.
Comment 3 Andrew G. Morgan 2024-11-09 23:10:32 UTC
This is an interesting detail that may help with shared libraries:

https://stackoverflow.com/a/27973583/14760867
Comment 4 Andrew G. Morgan 2024-11-10 07:14:26 UTC
I think I may have a new linkage strategy. More with the commits when I have more completely tested them.

Note You need to log in before you can comment on or make changes to this bug.