aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2022-01-23 16:35:23 -0800
committerAndrew G. Morgan <morgan@kernel.org>2022-01-23 16:35:23 -0800
commitbbabfb4cf4280825b5aeb96bf5354d654efa246e (patch)
tree81646850df82b7b68717d6cf53dca86fe482b3b0
parentf25a1b7e69f7b33e6afb58b3e38f3450b7d2d9a0 (diff)
downloadlibcap-bbabfb4cf4280825b5aeb96bf5354d654efa246e.tar.gz
Add a test case for a deadlock.
The CGO_ENABLED=0 failure mode is discussed in: https://github.com/golang/go/issues/50113 At the present time, this only passes when the psx package is compiled CGO_ENABLED=1. The problem being that a blocking read cannot be interrupted by the CGO_ENABLED=0 build of package "psx". It does not deadlock when compiled CGO_ENABLED=1 because the psx signal wakes the reading thread up back into user space. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--go/.gitignore2
-rw-r--r--go/Makefile20
-rw-r--r--go/psx-fd.go25
3 files changed, 44 insertions, 3 deletions
diff --git a/go/.gitignore b/go/.gitignore
index 9a88b0d..eca62ba 100644
--- a/go/.gitignore
+++ b/go/.gitignore
@@ -2,6 +2,8 @@ good-names.go
compare-cap
try-launching
try-launching-cgo
+psx-fd
+psx-fd-cgo
psx-signals
psx-signals-cgo
b210613
diff --git a/go/Makefile b/go/Makefile
index fb7d6ec..4aface4 100644
--- a/go/Makefile
+++ b/go/Makefile
@@ -83,6 +83,18 @@ ifeq ($(CGO_REQUIRED),0)
CC="$(CC)" CGO_ENABLED="1" $(CGO_LDFLAGS_ALLOW) $(GO) build $(GO_BUILD_FLAGS) -mod=vendor -o $@-cgo $<
endif
+# This is a test case developed from the deadlock investigation,
+# https://github.com/golang/go/issues/50113 . Note the psx-fd.go code
+# works when compiled CGO_ENABLED=1, but deadlocks when compiled
+# CGO_ENABLED=0. At the time of writing, this is true for go1.16+.
+psx-fd: psx-fd.go PSXGOPACKAGE
+ CC="$(CC)" CGO_ENABLED="$(CGO_REQUIRED)" $(CGO_LDFLAGS_ALLOW) $(GO) build $(GO_BUILD_FLAGS) -mod=vendor -o $@ $<
+
+ifeq ($(CGO_REQUIRED),0)
+psx-fd-cgo: psx-fd.go PSXGOPACKAGE
+ CC="$(CC)" CGO_ENABLED="1" $(CGO_LDFLAGS_ALLOW) $(GO) build $(GO_BUILD_FLAGS) -mod=vendor -o $@ $<
+endif
+
psx-signals: psx-signals.go PSXGOPACKAGE
CC="$(CC)" CGO_ENABLED="$(CGO_REQUIRED)" $(CGO_LDFLAGS_ALLOW) CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build $(GO_BUILD_FLAGS) -mod=vendor $<
@@ -110,16 +122,18 @@ mismatch-cgo: mismatch.go CAPGOPACKAGE
CC="$(CC)" CGO_ENABLED="1" $(CGO_LDFLAGS_ALLOW) CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build $(GO_BUILD_FLAGS) -mod=vendor -o $@ $<
endif
-test: setid gowns captree $(TESTS)
+test: setid gowns captree psx-fd $(TESTS)
CC="$(CC)" CGO_ENABLED="$(CGO_REQUIRED)" $(CGO_LDFLAGS_ALLOW) $(GO) test -mod=vendor $(IMPORTDIR)/psx
CC="$(CC)" CGO_ENABLED="$(CGO_REQUIRED)" $(CGO_LDFLAGS_ALLOW) $(GO) test -mod=vendor $(IMPORTDIR)/cap
LD_LIBRARY_PATH=../libcap ./compare-cap
./psx-signals
./mismatch || exit 0 ; exit 1
+ timeout 5 ./psx-fd || echo "this is a known Go bug"
ifeq ($(CGO_REQUIRED),0)
- $(MAKE) psx-signals-cgo mismatch-cgo
+ $(MAKE) psx-signals-cgo mismatch-cgo psx-fd-cgo
./psx-signals-cgo
./mismatch-cgo || exit 0 ; exit 1
+ ./psx-fd-cgo
endif
./setid --caps=false
./gowns -- -c "echo gowns runs"
@@ -167,5 +181,5 @@ clean:
rm -f compare-cap try-launching try-launching-cgo
rm -f $(topdir)/cap/*~ $(topdir)/psx/*~
rm -f b210613 b215283 b215283-cgo psx-signals psx-signals-cgo
- rm -f mismatch mismatch-cgo
+ rm -f mismatch mismatch-cgo psx-fd psx-fd-cgo
rm -fr vendor CAPGOPACKAGE PSXGOPACKAGE go.sum
diff --git a/go/psx-fd.go b/go/psx-fd.go
new file mode 100644
index 0000000..7aa3a76
--- /dev/null
+++ b/go/psx-fd.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "log"
+ "os"
+ "syscall"
+ "time"
+
+ "kernel.org/pub/linux/libs/security/libcap/psx"
+)
+
+const prSetKeepCaps = 8
+
+func main() {
+ r, w, err := os.Pipe()
+ if err != nil {
+ log.Fatalf("failed to obtain pipe: %v", err)
+ }
+ data := make([]byte, 2+r.Fd())
+ go r.Read(data)
+ time.Sleep(500 * time.Millisecond)
+ psx.Syscall3(syscall.SYS_PRCTL, prSetKeepCaps, 1, 0)
+ w.Close()
+ r.Close()
+}