diff options
author | Alexander Morozov <lk4d4math@gmail.com> | 2016-05-27 15:02:31 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2016-06-02 17:21:34 +0000 |
commit | 853cd1f4a61396cccb91522ed59af52d61aa8371 (patch) | |
tree | 6861440f3eab595ddb66791c84670873b4801d80 /src/syscall/exec_linux_test.go | |
parent | e90a49a0f5380c6f68502b1febfb73f696c2f610 (diff) | |
download | go-853cd1f4a61396cccb91522ed59af52d61aa8371.tar.gz go-853cd1f4a61396cccb91522ed59af52d61aa8371.zip |
syscall: call setgroups for no groups on GNU/Linux
Skip setgroups only for one particular case: GidMappings != nil and
GidMappingsEnableSetgroup == false and list of supplementary groups is
empty.
This patch returns pre-1.5 behavior for simple exec and still allows to
use GidMappings with non-empty Credential.
Change-Id: Ia91c77e76ec5efab7a7f78134ffb529910108fc1
Reviewed-on: https://go-review.googlesource.com/23524
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/syscall/exec_linux_test.go')
-rw-r--r-- | src/syscall/exec_linux_test.go | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go index 395dd99039..1afe88cb1b 100644 --- a/src/syscall/exec_linux_test.go +++ b/src/syscall/exec_linux_test.go @@ -26,7 +26,7 @@ func isChrooted(t *testing.T) bool { return root.Sys().(*syscall.Stat_t).Ino != 2 } -func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { +func checkUserNS(t *testing.T) { if _, err := os.Stat("/proc/self/ns/user"); err != nil { if os.IsNotExist(err) { t.Skip("kernel doesn't support user namespaces") @@ -56,6 +56,10 @@ func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") } +} + +func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { + checkUserNS(t) cmd := exec.Command("whoami") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUSER, @@ -161,3 +165,58 @@ func TestUnshare(t *testing.T) { t.Fatalf("Expected 3 lines of output, got %d", len(lines)) } } + +func TestGroupCleanup(t *testing.T) { + if os.Getuid() != 0 { + t.Skip("we need root for credential") + } + cmd := exec.Command("id") + cmd.SysProcAttr = &syscall.SysProcAttr{ + Credential: &syscall.Credential{ + Uid: 0, + Gid: 0, + }, + } + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } + strOut := strings.TrimSpace(string(out)) + expected := "uid=0(root) gid=0(root) groups=0(root)" + if strOut != expected { + t.Fatalf("id command output: %s, expected: %s", strOut, expected) + } +} + +func TestGroupCleanupUserNamespace(t *testing.T) { + if os.Getuid() != 0 { + t.Skip("we need root for credential") + } + checkUserNS(t) + cmd := exec.Command("id") + uid, gid := os.Getuid(), os.Getgid() + cmd.SysProcAttr = &syscall.SysProcAttr{ + Cloneflags: syscall.CLONE_NEWUSER, + Credential: &syscall.Credential{ + Uid: uint32(uid), + Gid: uint32(gid), + }, + UidMappings: []syscall.SysProcIDMap{ + {ContainerID: 0, HostID: uid, Size: 1}, + }, + GidMappings: []syscall.SysProcIDMap{ + {ContainerID: 0, HostID: gid, Size: 1}, + }, + } + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } + strOut := strings.TrimSpace(string(out)) + // there are two possible outs + expected1 := "uid=0(root) gid=0(root) groups=0(root)" + expected2 := "uid=0(root) gid=0(root) groups=0(root),65534(nobody)" + if strOut != expected1 && strOut != expected2 { + t.Fatalf("id command output: %s, expected: %s or %s", strOut, expected1, expected2) + } +} |