Upgrade libcap to libcap-2.48 am: 257a1ceb21 am: a444fa3c9c

Original change: https://android-review.googlesource.com/c/platform/external/libcap/+/1577304

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I8971b50e70e6a5e77ad6d6febd2ecf0beaddce6b
diff --git a/METADATA b/METADATA
index e30eaca..076bc04 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@
     type: GIT
     value: "https://git.kernel.org/pub/scm/linux/kernel/git/morgan/libcap.git"
   }
-  version: "libcap-2.47"
+  version: "libcap-2.48"
   license_type: NOTICE
   last_upgrade_date {
     year: 2021
-    month: 1
-    day: 25
+    month: 2
+    day: 5
   }
 }
diff --git a/Make.Rules b/Make.Rules
index 28af3c5..ded9014 100644
--- a/Make.Rules
+++ b/Make.Rules
@@ -1,7 +1,7 @@
 # Common version number defines for libcap
 LIBTITLE=libcap
 VERSION=2
-MINOR=47
+MINOR=48
 
 #
 ## Optional prefixes:
@@ -103,16 +103,21 @@
 PTHREADS ?= yes
 
 ifeq ($(PTHREADS),yes)
-GO := go
-GOLANG := $(shell if [ -n "$(shell $(GO) version 2>/dev/null)" ]; then echo yes ; else echo no ; fi)
+GO ?= go
+GOLANG ?= $(shell if [ -n "$(shell $(GO) version 2>/dev/null)" ]; then echo yes ; else echo no ; fi)
 ifeq ($(GOLANG),yes)
-GOROOT := $(shell $(GO) env GOROOT)
-GOCGO := $(shell if [ "$(shell $(GO) env CGO_ENABLED)" = 1 ]; then echo yes ; else echo no ; fi)
-GOOSARCH := $(shell $(GO) env GOHOSTOS)_$(shell $(GO) env GOHOSTARCH)
+GOROOT ?= $(shell $(GO) env GOROOT)
+GOCGO ?= $(shell if [ "$(shell $(GO) env CGO_ENABLED)" = 1 ]; then echo yes ; else echo no ; fi)
+GOOSARCH ?= $(shell $(GO) env GOHOSTOS)_$(shell $(GO) env GOHOSTARCH)
+CGO_REQUIRED=$(shell $(topdir)/go/cgo-required.sh $(GO))
+ifeq ($(CGO_REQUIRED),1)
+# Strictly speaking go1.15 doesn't need this, but 1.16 is when the
+# real golang support arrives for non-cgo support, so drop the last
+# vestige of legacy workarounds then.
+CGO_LDFLAGS_ALLOW := -Wl,-?-wrap[=,][^-.@][^,]*
+endif
 CGO_CFLAGS := -I$(topdir)/libcap/include
 CGO_LDFLAGS := -L$(topdir)/libcap
-CGO_LDFLAGS_ALLOW := -Wl,-?-wrap[=,][^-.@][^,]*
-CGO_REQUIRED=$(shell $(topdir)/go/cgo-required.sh)
 endif
 endif
 
diff --git a/Makefile b/Makefile
index 53ee901..7150b9b 100644
--- a/Makefile
+++ b/Makefile
@@ -42,32 +42,32 @@
 	cd .. && ln -s libcap libcap-$(VERSION).$(MINOR) && tar cvf libcap-$(VERSION).$(MINOR).tar --exclude patches libcap-$(VERSION).$(MINOR)/* && rm libcap-$(VERSION).$(MINOR)
 
 test: all
-	make -C libcap $@
-	make -C tests $@
+	$(MAKE) -C libcap $@
+	$(MAKE) -C tests $@
 ifneq ($(PAM_CAP),no)
 	$(MAKE) -C pam_cap $@
 endif
 ifeq ($(GOLANG),yes)
-	make -C go $@
+	$(MAKE) -C go $@
 endif
-	make -C progs $@
+	$(MAKE) -C progs $@
 
 sudotest: all
-	make -C tests $@
+	$(MAKE) -C tests $@
 ifneq ($(PAM_CAP),no)
 	$(MAKE) -C pam_cap $@
 endif
 ifeq ($(GOLANG),yes)
-	make -C go $@
+	$(MAKE) -C go $@
 endif
-	make -C progs $@
+	$(MAKE) -C progs $@
 
 distcheck:
 	./distcheck.sh
-	make DYNAMIC=yes clean all test sudotest
-	make CC=/usr/local/musl/bin/musl-gcc clean all test sudotest
-	make clean all test sudotest
-	make distclean
+	$(MAKE) DYNAMIC=yes clean all test sudotest
+	$(MAKE) CC=/usr/local/musl/bin/musl-gcc clean all test sudotest
+	$(MAKE) clean all test sudotest
+	$(MAKE) distclean
 
 morgangodoc:
 	@echo "Now the release is made, you want to remember to run:"
@@ -84,7 +84,7 @@
 	git tag -u D41A6DF2 -s v$(GOMAJOR).$(VERSION).$(MINOR) -m "This is the version tag for the 'libcap' Go base directory associated with libcap-$(VERSION).$(MINOR)."
 	git tag -u D41A6DF2 -s psx/v$(GOMAJOR).$(VERSION).$(MINOR) -m "This is the version tag for the 'psx' Go package associated with libcap-$(VERSION).$(MINOR)."
 	git tag -u D41A6DF2 -s cap/v$(GOMAJOR).$(VERSION).$(MINOR) -m "This is the version tag for the 'cap' Go package associated with libcap-$(VERSION).$(MINOR)."
-	make release
+	$(MAKE) release
 	@echo "sign the tar file using korg key"
 	cd .. && gpg -sba -u E2CCF3F4 libcap-$(VERSION).$(MINOR).tar
-	make morgangodoc
+	$(MAKE) morgangodoc
diff --git a/cap/file.go b/cap/file.go
index a3695b0..6658f1b 100644
--- a/cap/file.go
+++ b/cap/file.go
@@ -170,7 +170,7 @@
 // use file capabilities to become capable inside a namespace to be
 // administered by that UID. If capability aware code within that
 // namespace writes file capabilities without explicitly setting such
-// a UID, the kernel will fixup the capabilities to be specific to
+// a UID, the kernel will fix-up the capabilities to be specific to
 // that owner. In this way, the kernel prevents filesystem
 // capabilities from leaking out of that restricted namespace.
 func (c *Set) SetNSOwner(uid int) {
@@ -228,8 +228,8 @@
 //
 // Note, Linux does not store the full Effective Value Flag in the
 // metadata for the file. Only a single Effective bit is stored in
-// this metadata. This single bit is non-zero if the Permitted vector
-// has any overlapping bits with the Effective or Inheritable vector
+// this metadata. This single bit is non-zero if the Effective vector
+// has any overlapping bits with the Permitted or Inheritable vector
 // of c. This may appear suboptimal, but the reasoning behind it is
 // sound. Namely, the purpose of the Effective bit it to support
 // capabability unaware binaries that will only work if they magically
@@ -237,10 +237,10 @@
 // referred to simply as the 'legacy' bit). Without *full* support for
 // capability manipulation, as it is provided in this "../libcap/cap"
 // package, this was the only way for Go programs to make use of
-// capabilities.
+// file capabilities.
 //
 // The preferred way a binary will actually manipulate its
-// file-acquired capabilities is to carefully and deliberately using
+// file-acquired capabilities is to carefully and deliberately use
 // this package (or libcap, assisted by libpsx, for threaded C/C++
 // family code).
 func (c *Set) SetFd(file *os.File) error {
diff --git a/cap/go.mod b/cap/go.mod
index ca5b1c6..45e38fa 100644
--- a/cap/go.mod
+++ b/cap/go.mod
@@ -2,4 +2,4 @@
 
 go 1.11
 
-require kernel.org/pub/linux/libs/security/libcap/psx v0.2.47
+require kernel.org/pub/linux/libs/security/libcap/psx v0.2.48
diff --git a/contrib/seccomp/explore.go b/contrib/seccomp/explore.go
index b8249e0..37fe97b 100644
--- a/contrib/seccomp/explore.go
+++ b/contrib/seccomp/explore.go
@@ -45,32 +45,32 @@
 )
 
 const (
-	PR_SET_NO_NEW_PRIVS = 38
+	prSetNoNewPrivs = 38
 
-	SYS_SECCOMP               = 317        // x86_64 syscall number
-	SECCOMP_SET_MODE_FILTER   = 1          // uses user-supplied filter.
-	SECCOMP_FILTER_FLAG_TSYNC = (1 << 0)   // mirror filtering on all threads.
-	SECCOMP_RET_ERRNO         = 0x00050000 // returns an errno
-	SECCOMP_RET_DATA          = 0x0000ffff // mask for RET data payload (ex. errno)
-	SECCOMP_RET_KILL_PROCESS  = 0x80000000 // kill the whole process immediately
-	SECCOMP_RET_TRAP          = 0x00030000 // disallow and force a SIGSYS
-	SECCOMP_RET_ALLOW         = 0x7fff0000
+	sysSeccomp             = 317        // x86_64 syscall number
+	seccompSetModeFilter   = 1          // uses user-supplied filter.
+	seccompFilterFlagTsync = (1 << 0)   // mirror filtering on all threads.
+	seccompRetErrno        = 0x00050000 // returns an errno
+	seccompRetData         = 0x0000ffff // mask for RET data payload (ex. errno)
+	seccompRetKillProcess  = 0x80000000 // kill the whole process immediately
+	seccompRetTrap         = 0x00030000 // disallow and force a SIGSYS
+	seccompRetAllow        = 0x7fff0000
 
-	BPF_LD  = 0x00
-	BPF_JMP = 0x05
-	BPF_RET = 0x06
+	bpfLd  = 0x00
+	bpfJmp = 0x05
+	bpfRet = 0x06
 
-	BPF_W = 0x00
+	bpfW = 0x00
 
-	BPF_ABS = 0x20
-	BPF_JEQ = 0x10
+	bpfAbs = 0x20
+	bpfJeq = 0x10
 
-	BPF_K = 0x00
+	bpfK = 0x00
 
-	AUDIT_ARCH_X86_64 = 3221225534 // HACK: I don't understand this value
-	ARCH_NR           = AUDIT_ARCH_X86_64
+	auditArchX86_64 = 3221225534 // HACK: I don't understand this value
+	archNr          = auditArchX86_64
 
-	syscall_nr = 0
+	syscallNr = 0
 )
 
 // SockFilter is a single filter block.
@@ -95,66 +95,67 @@
 	Filter *SockFilter
 }
 
+// SockFilterSlice is a subprogram filter.
 type SockFilterSlice []SockFilter
 
-func BPF_STMT(code uint16, k uint32) SockFilter {
+func bpfStmt(code uint16, k uint32) SockFilter {
 	return SockFilter{code, 0, 0, k}
 }
 
-func BPF_JUMP(code uint16, k uint32, jt uint8, jf uint8) SockFilter {
+func bpfJump(code uint16, k uint32, jt uint8, jf uint8) SockFilter {
 	return SockFilter{code, jt, jf, k}
 }
 
-func ValidateArchitecture() []SockFilter {
+func validateArchitecture() []SockFilter {
 	return []SockFilter{
-		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 4), // HACK: I don't understand this 4.
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0),
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL_PROCESS),
+		bpfStmt(bpfLd+bpfW+bpfAbs, 4), // HACK: I don't understand this 4.
+		bpfJump(bpfJmp+bpfJeq+bpfK, archNr, 1, 0),
+		bpfStmt(bpfRet+bpfK, seccompRetKillProcess),
 	}
 }
 
 func ExamineSyscall() []SockFilter {
 	return []SockFilter{
-		BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
+		bpfStmt(bpfLd+bpfW+bpfAbs, syscallNr),
 	}
 }
 
 func AllowSyscall(syscallNum uint32) []SockFilter {
 	return []SockFilter{
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscallNum, 0, 1),
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		bpfJump(bpfJmp+bpfJeq+bpfK, syscallNum, 0, 1),
+		bpfStmt(bpfRet+bpfK, seccompRetAllow),
 	}
 }
 
 func DisallowSyscall(syscallNum, errno uint32) []SockFilter {
 	return []SockFilter{
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscallNum, 0, 1),
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(errno&SECCOMP_RET_DATA)),
+		bpfJump(bpfJmp+bpfJeq+bpfK, syscallNum, 0, 1),
+		bpfStmt(bpfRet+bpfK, seccompRetErrno|(errno&seccompRetData)),
 	}
 }
 
 func KillProcess() []SockFilter {
 	return []SockFilter{
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL_PROCESS),
+		bpfStmt(bpfRet+bpfK, seccompRetKillProcess),
 	}
 }
 
 func NotifyProcessAndDie() []SockFilter {
 	return []SockFilter{
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+		bpfStmt(bpfRet+bpfK, seccompRetTrap),
 	}
 }
 
 func TrapOnSyscall(syscallNum uint32) []SockFilter {
 	return []SockFilter{
-		BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, syscallNum, 0, 1),
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+		bpfJump(bpfJmp+bpfJeq+bpfK, syscallNum, 0, 1),
+		bpfStmt(bpfRet+bpfK, seccompRetTrap),
 	}
 }
 
 func AllGood() []SockFilter {
 	return []SockFilter{
-		BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+		bpfStmt(bpfRet+bpfK, seccompRetAllow),
 	}
 }
 
@@ -178,10 +179,10 @@
 	return nil
 }
 
-// seccomp_set_mode_filter is our wrapper for performing our seccomp system call.
+// SeccompSetModeFilter is our wrapper for performing our seccomp system call.
 //go:uintptrescapes
-func seccomp_set_mode_filter(prog *SockFProg) error {
-	if _, _, e := syscall.RawSyscall(SYS_SECCOMP, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, uintptr(unsafe.Pointer(prog))); e != 0 {
+func SeccompSetModeFilter(prog *SockFProg) error {
+	if _, _, e := syscall.RawSyscall(sysSeccomp, seccompSetModeFilter, seccompFilterFlagTsync, uintptr(unsafe.Pointer(prog))); e != 0 {
 		return e
 	}
 	return nil
@@ -220,12 +221,12 @@
 	}
 
 	// This is required to load a filter without privilege.
-	if err := prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0, 0); err != nil {
+	if err := prctl(prSetNoNewPrivs, 1, 0, 0, 0, 0); err != nil {
 		log.Fatalf("Prctl(PR_SET_NO_NEW_PRIVS): %v", err)
 	}
 
 	fmt.Println("Applying syscall policy...")
-	if err := seccomp_set_mode_filter(prog); err != nil {
+	if err := SeccompSetModeFilter(prog); err != nil {
 		log.Fatalf("seccomp_set_mode_filter: %v", err)
 	}
 	fmt.Println("...Policy applied")
@@ -240,7 +241,7 @@
 	}
 
 	var filter []SockFilter
-	filter = append(filter, ValidateArchitecture()...)
+	filter = append(filter, validateArchitecture()...)
 
 	// Grab the system call number.
 	filter = append(filter, ExamineSyscall()...)
diff --git a/contrib/seccomp/go.mod b/contrib/seccomp/go.mod
index d9efa2e..86e40c6 100644
--- a/contrib/seccomp/go.mod
+++ b/contrib/seccomp/go.mod
@@ -2,4 +2,4 @@
 
 go 1.14
 
-require kernel.org/pub/linux/libs/security/libcap/psx v0.2.47
+require kernel.org/pub/linux/libs/security/libcap/psx v0.2.48
diff --git a/doc/libpsx.3 b/doc/libpsx.3
index a3535a6..61baa88 100644
--- a/doc/libpsx.3
+++ b/doc/libpsx.3
@@ -1,4 +1,4 @@
-.TH LIBPSX 3 "2020-10-13" "" "Linux Programmer's Manual"
+.TH LIBPSX 3 "2021-01-31" "" "Linux Programmer's Manual"
 .SH NAME
 psx_syscall3, psx_syscall6 \- POSIX semantics for system calls
 .SH SYNOPSIS
@@ -36,7 +36,9 @@
 mechanism uses signo=33 (which is hidden by glibc below a redefined
 SIGRTMIN),
 .B libpsx
-usurps SIGRTMAX for this process.
+inserts itself in the SIGSYS handler stack. It goes to great length to
+be the first such handler but acts as a pass-through for other SIGSYS
+uses.
 .PP
 A linker trick of
 .I wrapping
@@ -73,7 +75,10 @@
 .SH CONFORMING TO
 The needs of
 .BR libcap (3)
-for POSIX semantics of capability manipulation.
+for POSIX semantics of capability manipulation. You can read more
+about why this is needed here:
+.TP
+https://sites.google.com/site/fullycapable/who-ordered-libpsx
 .SH "REPORTING BUGS"
 Please report bugs via:
 .TP
diff --git a/go/.gitignore b/go/.gitignore
index 30ae0b6..c0a9737 100644
--- a/go/.gitignore
+++ b/go/.gitignore
@@ -3,6 +3,7 @@
 try-launching
 try-launching-cgo
 psx-signals
+psx-signals-cgo
 b210613
 mknames
 web
diff --git a/go/Makefile b/go/Makefile
index b8745f1..757844a 100644
--- a/go/Makefile
+++ b/go/Makefile
@@ -76,12 +76,11 @@
 	GO111MODULE=off CGO_ENABLED="1" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH=$(GOPATH) $(GO) build -o $@-cgo $<
 endif
 
-# Bug reported issues:
-#   https://bugzilla.kernel.org/show_bug.cgi?id=210533 (cgo - fixed)
-#   https://github.com/golang/go/issues/43149 (nocgo - not fixed yet)
-# When the latter is fixed we can replace CGO_ENABLED=1 with ="$(CGO_REQUIRED)"
-psx-signals: psx-signals.go  $(PSXGOPACKAGE)
-	GO111MODULE=off CGO_ENABLED=1 CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" GOPATH=$(GOPATH) $(GO) build $<
+psx-signals: psx-signals.go $(PSXGOPACKAGE)
+	GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" GOPATH=$(GOPATH) $(GO) build $<
+ifeq ($(CGO_REQUIRED),0)
+	GO111MODULE=off CGO_ENABLED="1" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" GOPATH=$(GOPATH) $(GO) build -o $@-cgo $<
+endif
 
 b210613: b210613.go $(CAPGOPACKAGE)
 	GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" GOPATH=$(GOPATH) $(GO) build $<
@@ -91,6 +90,9 @@
 	GO111MODULE=off CGO_ENABLED="$(CGO_REQUIRED)" CGO_LDFLAGS_ALLOW="$(CGO_LDFLAGS_ALLOW)" GOPATH="$(GOPATH)" $(GO) test $(IMPORTDIR)/cap
 	LD_LIBRARY_PATH=../libcap ./compare-cap
 	./psx-signals
+ifeq ($(CGO_REQUIRED),0)
+	./psx-signals-cgo
+endif
 	./setid --caps=false
 	./gowns -- -c "echo gowns runs"
 
@@ -122,5 +124,5 @@
 	rm -f web setid gowns
 	rm -f compare-cap try-launching try-launching-cgo
 	rm -f $(topdir)/cap/*~ $(topdir)/psx/*~
-	rm -f psx-signals b210613
+	rm -f b210613 psx-signals psx-signals-cgo
 	rm -fr pkg src
diff --git a/go/cgo-required.sh b/go/cgo-required.sh
index 7551138..f9afa52 100755
--- a/go/cgo-required.sh
+++ b/go/cgo-required.sh
@@ -4,8 +4,13 @@
 # available to the working go runtime or not. If it isn't we always
 # have to use libcap/psx to get POSIX semantics for syscalls that
 # change security state.
+if [ -n "$1" ]; then
+    export GO="${1}"
+else
+    export GO=go
+fi
 
-if [ -z "$(go doc syscall 2>/dev/null|grep AllThreadsSyscall)" ]; then
+if [ -z "$(${GO} doc syscall 2>/dev/null|grep AllThreadsSyscall)" ]; then
     echo "1"
 else
     echo "0"
diff --git a/goapps/gowns/go.mod b/goapps/gowns/go.mod
index 3863fbb..bc534af 100644
--- a/goapps/gowns/go.mod
+++ b/goapps/gowns/go.mod
@@ -2,4 +2,4 @@
 
 go 1.15
 
-require kernel.org/pub/linux/libs/security/libcap/cap v0.2.47
+require kernel.org/pub/linux/libs/security/libcap/cap v0.2.48
diff --git a/goapps/setid/go.mod b/goapps/setid/go.mod
index b227144..cd2282d 100644
--- a/goapps/setid/go.mod
+++ b/goapps/setid/go.mod
@@ -3,6 +3,6 @@
 go 1.11
 
 require (
-	kernel.org/pub/linux/libs/security/libcap/cap v0.2.47
-	kernel.org/pub/linux/libs/security/libcap/psx v0.2.47
+	kernel.org/pub/linux/libs/security/libcap/cap v0.2.48
+	kernel.org/pub/linux/libs/security/libcap/psx v0.2.48
 )
diff --git a/goapps/web/go.mod b/goapps/web/go.mod
index a2dac7d..f7ae28b 100644
--- a/goapps/web/go.mod
+++ b/goapps/web/go.mod
@@ -2,4 +2,4 @@
 
 go 1.11
 
-require kernel.org/pub/linux/libs/security/libcap/cap v0.2.47
+require kernel.org/pub/linux/libs/security/libcap/cap v0.2.48
diff --git a/libcap/Makefile b/libcap/Makefile
index 230be39..9563d88 100644
--- a/libcap/Makefile
+++ b/libcap/Makefile
@@ -28,18 +28,18 @@
 
 all: pcs $(STACAPLIBNAME)
 ifeq ($(SHARED),yes)
-	make $(CAPLIBNAME)
+	$(MAKE) $(CAPLIBNAME)
 endif
 ifeq ($(PTHREADS),yes)
-	make $(STAPSXLIBNAME)
+	$(MAKE) $(STAPSXLIBNAME)
 ifeq ($(SHARED),yes)
-	make $(PSXLIBNAME)
+	$(MAKE) $(PSXLIBNAME)
 endif
 endif
 
 pcs: libcap.pc
 ifeq ($(PTHREADS),yes)
-	make libpsx.pc
+	$(MAKE) libpsx.pc
 endif
 
 ifeq ($(BUILD_GPERF),yes)
@@ -88,8 +88,8 @@
 	$(AR) rcs $@ $^
 	$(RANLIB) $@
 
-$(STAPSXLIBNAME): $(PSXOBJS)
-	$(AR) rcs $@ $^
+$(STAPSXLIBNAME): $(PSXOBJS) include/sys/psx_syscall.h
+	$(AR) rcs $@ $(PSXOBJS)
 	$(RANLIB) $@
 
 ifeq ($(SHARED),yes)
@@ -98,8 +98,8 @@
 	ln -sf $(MINCAPLIBNAME) $(MAJCAPLIBNAME)
 	ln -sf $(MAJCAPLIBNAME) $(CAPLIBNAME)
 
-$(PSXLIBNAME) $(MAJPSXLIBNAME) $(MINPSXLIBNAME): $(PSXOBJS)
-	$(LD) $(CFLAGS) $(LDFLAGS) -Wl,-soname,$(MAJPSXLIBNAME) -o $(MINPSXLIBNAME) $^ $(PSXLINKFLAGS)
+$(PSXLIBNAME) $(MAJPSXLIBNAME) $(MINPSXLIBNAME): $(PSXOBJS) include/sys/psx_syscall.h
+	$(LD) $(CFLAGS) $(LDFLAGS) -Wl,-soname,$(MAJPSXLIBNAME) -o $(MINPSXLIBNAME) $(PSXOBJS) $(PSXLINKFLAGS)
 	ln -sf $(MINPSXLIBNAME) $(MAJPSXLIBNAME)
 	ln -sf $(MAJPSXLIBNAME) $(PSXLIBNAME)
 endif
@@ -118,27 +118,27 @@
 
 install: install-static
 ifeq ($(SHARED),yes)
-	make install-shared
+	$(MAKE) install-shared
 endif
 
 install-static: install-static-cap
 ifeq ($(PTHREADS),yes)
-	make install-static-psx
+	$(MAKE) install-static-psx
 endif
 
 install-shared: install-shared-cap
 ifeq ($(PTHREADS),yes)
-	make install-shared-psx
+	$(MAKE) install-shared-psx
 endif
 
 install-cap: install-static-cap
 ifeq ($(SHARED),yes)
-	make install-shared-cap
+	$(MAKE) install-shared-cap
 endif
 
 install-psx: install-static-psx
 ifeq ($(SHARED),yes)
-	make install-shared-psx
+	$(MAKE) install-shared-psx
 endif
 
 install-static-cap: install-common-cap $(STACAPLIBNAME)
@@ -167,7 +167,11 @@
 	install -m 0644 include/sys/capability.h $(FAKEROOT)$(INCDIR)/sys
 	install -m 0644 libcap.pc $(FAKEROOT)$(PKGCONFIGDIR)/libcap.pc
 
-install-common-psx: install-common libpsx.pc
+include/sys/psx_syscall.h: ../psx/psx_syscall.h
+	rm -f $@
+	ln -s ../../../psx/psx_syscall.h $@
+
+install-common-psx: install-common libpsx.pc include/sys/psx_syscall.h
 	install -m 0644 include/sys/psx_syscall.h $(FAKEROOT)$(INCDIR)/sys
 	install -m 0644 libpsx.pc $(FAKEROOT)$(PKGCONFIGDIR)/libpsx.pc
 
@@ -181,4 +185,5 @@
 	rm -f $(CAPOBJS) $(CAPLIBNAME)* $(STACAPLIBNAME) libcap.pc
 	rm -f $(PSXOBJS) $(PSXLIBNAME)* $(STAPSXLIBNAME) libpsx.pc
 	rm -f cap_names.h cap_names.list.h _makenames $(GPERF_OUTPUT) cap_test
+	rm -f include/sys/psx_syscall.h
 	cd include/sys && $(LOCALCLEAN)
diff --git a/libcap/include/sys/.gitignore b/libcap/include/sys/.gitignore
new file mode 100644
index 0000000..595fc39
--- /dev/null
+++ b/libcap/include/sys/.gitignore
@@ -0,0 +1 @@
+psx_syscall.h
diff --git a/libcap/include/sys/psx_syscall.h b/libcap/include/sys/psx_syscall.h
deleted file mode 120000
index ebac5fe..0000000
--- a/libcap/include/sys/psx_syscall.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../psx/psx_syscall.h
\ No newline at end of file
diff --git a/libcap/psx_syscall.h b/libcap/psx_syscall.h
deleted file mode 120000
index dc748bb..0000000
--- a/libcap/psx_syscall.h
+++ /dev/null
@@ -1 +0,0 @@
-include/sys/psx_syscall.h
\ No newline at end of file
diff --git a/psx/README b/psx/README
index c25538a..cd9c651 100644
--- a/psx/README
+++ b/psx/README
@@ -1,20 +1,28 @@
-Package psx provides a CGo backed API for invoking system calls in a
-way that each system call is mirrored on all pthreads of the combined
-Go/CGo runtime. Since the Go runtime treats all pthreads as
-interchangeable, a feature like this is needed to meaningfully change
-process privilege (including dropping privilege) in a Go program
-running on Linux. This package is required by:
+Package "psx" provides an API for invoking system calls in a way that
+each system call is mirrored on all OS threads of the combined Go/CGo
+runtime. Since the Go runtime treats OS threads as interchangeable, a
+feature like this is needed to meaningfully change process privilege
+(including dropping privilege) in a Go program running on Linux. This
+package is required by:
 
    "kernel.org/pub/linux/libs/security/libcap/cap"
 
-The functionality is implemented by a C library: libpsx, which is
-distributed with the libcap. The official release announcement site
-for libcap and libpsx is:
+When compiled CGO_ENABLED=0, the functionality requires go1.16+ to
+build. That release of Go introduced syscall.AllThreadsSyscall*()
+APIs.  When compiled this way, the "psx" package functions
+psx.Syscall3() and psx.Syscall6() are aliased to
+syscall.AllThreadsSyscall() and syscall.AllThreadsSyscall6()
+respectively.
+
+When compiled CGO_ENABLED=1, the functionality is implemented by C
+code, [lib]psx, which is distributed with libcap.
+
+The official release announcement site for libcap and libpsx is:
 
    https://sites.google.com/site/fullycapable/
 
-Like libcap/libpsx itself, the psx package is distributed with a "you
-choose" License. Specifically: BSD three clause, or GPL2. See the
+Like libcap/libpsx itself, the "psx" package is distributed with a
+"you choose" License. Specifically: BSD three clause, or GPL2. See the
 LICENSE file.
 
 Andrew G. Morgan <[email protected]>
diff --git a/psx/psx.c b/psx/psx.c
index 38251ed..4de3653 100644
--- a/psx/psx.c
+++ b/psx/psx.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019,20 Andrew G Morgan <[email protected]>
+ * Copyright (c) 2019-21 Andrew G Morgan <[email protected]>
  *
  * This file contains a collection of routines that perform thread
  * synchronization to ensure that a whole process is running as a
@@ -30,12 +30,12 @@
 #include "psx_syscall.h"
 
 /*
- * psx_load_syscalls() is weakly defined so we can have it overridden
- * by libpsx if it is linked. Specifically, when libcap calls
- * psx_load_sycalls it will override their defaut values. As can be
- * seen here this present function is a no-op. However, if libpsx is
- * linked, the one present in that library (not being weak) will
- * replace this one.
+ * psx_load_syscalls() can be weakly defined in dependent libraries to
+ * provide a mechanism for a library to optionally leverage this psx
+ * mechanism. Specifically, when libcap calls psx_load_sycalls() it
+ * provides a weakly declared default that maps its system calls to
+ * the regular system call functions. However, when linked with psx,
+ * this function here overrides the syscalls to be the psx ones.
  */
 void psx_load_syscalls(long int (**syscall_fn)(long int,
 					      long int, long int, long int),
@@ -96,7 +96,8 @@
 
 /*
  * psx_action_key is used for thread local storage of the thread's
- * registration. */
+ * registration.
+ */
 pthread_key_t psx_action_key;
 
 /*
diff --git a/psx/psx.go b/psx/psx.go
index b1b530a..529f19d 100644
--- a/psx/psx.go
+++ b/psx/psx.go
@@ -7,6 +7,8 @@
 	"syscall"
 )
 
+// Syscall3 and Syscall6 are aliases for syscall.AllThreadsSyscall*
+// when compiled CGO_ENABLED=0.
 var (
 	Syscall3 = syscall.AllThreadsSyscall
 	Syscall6 = syscall.AllThreadsSyscall6