diff options
-rw-r--r-- | .github/workflows/ci.yml | 2 | ||||
-rw-r--r-- | internal/syscallcompat/thread_credentials.go | 32 | ||||
-rw-r--r-- | internal/syscallcompat/thread_credentials_368_arm.go | 35 | ||||
-rw-r--r-- | internal/syscallcompat/thread_credentials_other.go | 35 |
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 +} |