aboutsummaryrefslogtreecommitdiff
path: root/psx
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2019-11-30 18:33:42 -0800
committerAndrew G. Morgan <morgan@kernel.org>2019-12-06 23:06:47 -0800
commitb2b267ef1c83f1f3d3105a4bb84f8bebbc130dec (patch)
treed0be8e0daca097a3911006b9eb85fcf4d2607182 /psx
parente9f55d90e482f680504487be6b3afb80865691d6 (diff)
downloadlibcap-b2b267ef1c83f1f3d3105a4bb84f8bebbc130dec.tar.gz
Add support to libcap for overriding system call functions.
Note, this override only supports the system calls that libcap uses to change kernel state associated with the current process. This is primarily intended to permit the user to use libpsx to force all pthreads to mirror capability and other security relevant state. Use a weak function definition feature of libpsx share_psx_syscall() to transparently arrange for libcap to so force itself to use the psx_syscall() abstraction when linked against -lpsx. This has the effect of using linker magic to make libcap transparently observe POSIX semantics for security state setting operations. That is, when linked as follows: gcc .... -lcap -lpsx -lpthread -Wl,-wrap,pthread_create all pthreads maintain a common security state with respect to the libcap API. This also adds full capability setting support to the Go package libcap/cap via a libcap/psx package which uses cgo+libpsx syscalls that share capabilities over all pthreads including those of the Go runtime. Finally, if Go supports syscall.PosixSyscall() etc. then provide a non-psx mechanism for libcap/cap to "just work" in all Go code. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'psx')
-rw-r--r--psx/psx.go37
-rw-r--r--psx/psx_test.go24
2 files changed, 61 insertions, 0 deletions
diff --git a/psx/psx.go b/psx/psx.go
new file mode 100644
index 0000000..e90297d
--- /dev/null
+++ b/psx/psx.go
@@ -0,0 +1,37 @@
+// Package psx provides Go wrappers for two system call functions that
+// work by calling the C libpsx functions of these names.
+package psx
+
+import (
+ "syscall"
+)
+
+// #cgo LDFLAGS: -lpsx -lpthread -Wl,-wrap,pthread_create
+//
+// #include <errno.h>
+// #include <sys/psx_syscall.h>
+//
+// long __errno_too() { return errno ; }
+import "C"
+
+// Syscall3 performs a 3 argument syscall using the libpsx C function
+// psx_syscall3().
+func Syscall3(syscallnr, arg1, arg2, arg3 uintptr) (uintptr, uintptr, syscall.Errno) {
+ v := C.psx_syscall3(C.long(syscallnr), C.long(arg1), C.long(arg2), C.long(arg3))
+ var errno syscall.Errno
+ if v < 0 {
+ errno = syscall.Errno(C.__errno_too())
+ }
+ return uintptr(v), uintptr(v), errno
+}
+
+// Syscall6 performs a 6 argument syscall using the libpsx C function
+// psx_syscall6()
+func Syscall6(syscallnr, arg1, arg2, arg3, arg4, arg5, arg6 uintptr) (uintptr, uintptr, syscall.Errno) {
+ v := C.psx_syscall6(C.long(syscallnr), C.long(arg1), C.long(arg2), C.long(arg3), C.long(arg4), C.long(arg5), C.long(arg6))
+ var errno syscall.Errno
+ if v < 0 {
+ errno = syscall.Errno(C.__errno_too())
+ }
+ return uintptr(v), uintptr(v), errno
+}
diff --git a/psx/psx_test.go b/psx/psx_test.go
new file mode 100644
index 0000000..8dd67ca
--- /dev/null
+++ b/psx/psx_test.go
@@ -0,0 +1,24 @@
+package psx
+
+import (
+ "syscall"
+ "testing"
+)
+
+func TestSyscall3(t *testing.T) {
+ want := syscall.Getpid()
+ if got, _, err := Syscall3(syscall.SYS_GETPID, 0, 0, 0); err != 0 {
+ t.Errorf("failed to get PID via libpsx: %v", err)
+ } else if int(got) != want {
+ t.Errorf("pid mismatch: got=%d want=%d", got, want)
+ }
+}
+
+func TestSyscall6(t *testing.T) {
+ want := syscall.Getpid()
+ if got, _, err := Syscall6(syscall.SYS_GETPID, 0, 0, 0, 0, 0, 0); err != 0 {
+ t.Errorf("failed to get PID via libpsx: %v", err)
+ } else if int(got) != want {
+ t.Errorf("pid mismatch: got=%d want=%d", got, want)
+ }
+}