aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--internal/syscallcompat/thread_credentials.go32
-rw-r--r--internal/syscallcompat/thread_credentials_368_arm.go35
-rw-r--r--internal/syscallcompat/thread_credentials_other.go35
4 files changed, 103 insertions, 1 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index abda518..e9b2a12 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -46,7 +46,7 @@ jobs:
# Build & upload static binary
- run: ./build-without-openssl.bash
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
with:
name: gocryptfs static binary (Go ${{ matrix.go }})
path: gocryptfs
diff --git a/internal/syscallcompat/thread_credentials.go b/internal/syscallcompat/thread_credentials.go
new file mode 100644
index 0000000..3ef5233
--- /dev/null
+++ b/internal/syscallcompat/thread_credentials.go
@@ -0,0 +1,32 @@
+//go:build linux
+
+// golang.org/x/sys/unix commit
+// https://github.com/golang/sys/commit/d0df966e6959f00dc1c74363e537872647352d51
+// changed unix.Setreuid/unix.Setregid functions to affect the whole thread, which is
+// what gocryptfs does NOT want (https://github.com/rfjakob/gocryptfs/issues/893).
+// The functions Setreuid/Setegid are copy-pasted from one commit before
+// (9e1f76180b77a12eb07c82eb8e1ea8a7f8d202e7).
+//
+// Looking at the diff at https://github.com/golang/sys/commit/d0df966e6959f00dc1c74363e537872647352d51
+// we see that only two architectures, 386 and arm, use SYS_SETREUID32/SYS_SETREGID32
+// (see "man 2 setreuid" for why).
+// All the others architectures use SYS_SETREUID/SYS_SETREGID.
+//
+// As of golang.org/x/sys/unix v0.30.0, Setgroups/setgroups is still per-thread, but
+// it is likely that this will change, too. Setgroups/setgroups are copy-pasted from
+// v0.30.0. The SYS_SETGROUPS32/SYS_SETGROUPS split is the same as for Setreuid.
+//
+// Note: _Gid_t is always uint32 on linux, so we can directly use uint32 for setgroups.
+package syscallcompat
+
+func Setgroups(gids []int) (err error) {
+ if len(gids) == 0 {
+ return setgroups(0, nil)
+ }
+
+ a := make([]uint32, len(gids))
+ for i, v := range gids {
+ a[i] = uint32(v)
+ }
+ return setgroups(len(a), &a[0])
+}
diff --git a/internal/syscallcompat/thread_credentials_368_arm.go b/internal/syscallcompat/thread_credentials_368_arm.go
new file mode 100644
index 0000000..1244160
--- /dev/null
+++ b/internal/syscallcompat/thread_credentials_368_arm.go
@@ -0,0 +1,35 @@
+//go:build (linux && 386) || (linux && arm)
+
+package syscallcompat
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/unix"
+)
+
+// See thread_credentials.go for docs
+
+func Setreuid(ruid int, euid int) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func Setregid(rgid int, egid int) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func setgroups(n int, list *uint32) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
diff --git a/internal/syscallcompat/thread_credentials_other.go b/internal/syscallcompat/thread_credentials_other.go
new file mode 100644
index 0000000..e3c78d0
--- /dev/null
+++ b/internal/syscallcompat/thread_credentials_other.go
@@ -0,0 +1,35 @@
+//go:build !((linux && 386) || (linux && arm))
+
+package syscallcompat
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/unix"
+)
+
+// See thread_credentials.go for docs
+
+func Setreuid(ruid int, euid int) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func Setregid(rgid int, egid int) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func setgroups(n int, list *uint32) (err error) {
+ _, _, e1 := unix.RawSyscall(unix.SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}