Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall.TestSetuidEtc() fails in some container setups #46145

Closed
AndrewGMorgan opened this issue May 12, 2021 · 8 comments
Closed

syscall.TestSetuidEtc() fails in some container setups #46145

AndrewGMorgan opened this issue May 12, 2021 · 8 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@AndrewGMorgan
Copy link
Contributor

AndrewGMorgan commented May 12, 2021

What version of Go are you using (go version)?

HEAD

Does this issue reproduce with the latest release?

Yes, this build test is present at HEAD and in the go1.16 release branch

What operating system and processor architecture are you using (go env)?

All flavors of Linux

What did you do?

User ran all.bash in a non-default restrictive environment with a non-default bounding set.

What did you expect to see?

Given the fact the test cannot run successfully in this environment, the test might better be skipped.

What did you see instead?

Linux 7bb298e4-71d7-4f5e-4d4c-d58ac8ce61ac 4.15.0-76-generic #86-Ubuntu SMP Fri Jan 17 17:24:28 UTC 2020 x86_64

<redacted for clarity>
--- FAIL: TestSetuidEtc (0.12s)
syscall_linux_test.go:668: [6] "Setgroups([]int{0,1,2,3})" comparison: "/proc/32911/status" got:"Groups:\t1 2 3 0" want:"Groups:\t0 1 2 3" (bad) [pid=32911 file:'Name: syscall.test
Umask: 0022
State: S (sleeping)
Tgid: 32911
Ngid: 0
Pid: 32911
PPid: 10324
TracerPid: 0
Uid: 0 0 0 0
Gid: 0 0 0 0
FDSize: 64
Groups: 1 2 3 0
NStgid: 32911
NSpid: 32911
NSpgid: 7
NSsid: 7
VmPeak: 1092152 kB
VmSize: 1034812 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 5372 kB
VmRSS: 5372 kB
RssAnon: 1416 kB
RssFile: 3956 kB
RssShmem: 0 kB
VmData: 169344 kB
VmStk: 132 kB
VmExe: 1384 kB
VmLib: 1464 kB
VmPTE: 140 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
Threads: 8
SigQ: 2/128577
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000300000
SigCgt: fffffffdffc1feff
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 2
Speculation_Store_Bypass: thread force mitigated
Cpus_allowed: ff
Cpus_allowed_list: 0-7
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 22
nonvoluntary_ctxt_switches: 52
' Pid: 32911]
FAIL
FAIL syscall 0.724s

<redacted for clarity>
@AndrewGMorgan
Copy link
Contributor Author

@ianlancetaylor
Copy link
Contributor

Note that syscall_linux_test.go already has some tests that are only run by root, such as TestLinuxDeathSignal.

@ianlancetaylor ianlancetaylor added the NeedsFix The path to resolution is known, but the work has not been done. label May 13, 2021
@ianlancetaylor ianlancetaylor added this to the Go1.17 milestone May 13, 2021
@AndrewGMorgan
Copy link
Contributor Author

So, the issue is that the proc file is listing the supplementary groups in an unsorted order. This is not expected by the test.

syscall_linux_test.go:668: [6] "Setgroups([]int{0,1,2,3})" comparison: "/proc/32911/status" got:"Groups:\t1 2 3 0" want:"Groups:\t0 1 2 3" (bad) [pid=32911 file:'Name: syscall.test...

I'll explore a little and see if I can reproduce this behavior.

@AndrewGMorgan
Copy link
Contributor Author

On my Chromebox linux-in-a-container, the /proc/self/gid_map file looks like this:

$ cat /proc/self/gid_map 
         0    1000000       1000
      1000       1000          1
      1001       1001          1
      1002    1001002     654358
    655360     655360          1
    655361    1655361       9996
    665357     665357          1
    665358    1665358  999334642

Further,

$ grep Groups /proc/self/status 
Groups: 1000 1001 665357 20 24 25 27 29 44 46 100 109 

Which is clearly unsorted. On this system, the setgroups call seems to generate the sorted order for the groups after gid-mapping via the above file:

$ sudo /sbin/capsh --groups=0,1,2,3 -- -c "grep Groups /proc/self/status"
Groups: 0 1 2 3 
$ sudo /sbin/capsh --groups=0,1,2,3,999,1000,1001,1002 -- -c "grep Groups /proc/self/status"
Groups: 1000 1001 0 1 2 3 999 1002 

The first example there is what the test is doing (which explains why the test passes for me and likely common container setups), but the second one suggests that, depending on the gid_map file prevalent when all.bash is run, the sorted order for the trivial 0,1,2,3 case can actually be different.

I think that explains what is going on. How to work around it is less clear. Yet more parsing of the status lines I guess...

@AndrewGMorgan
Copy link
Contributor Author

Indeed, as expected, making this modification to the test causes it to fail in my container:

$ git diff
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go
index adeb7c9ebb..4c1322c3a3 100644
--- a/src/syscall/syscall_linux_test.go
+++ b/src/syscall/syscall_linux_test.go
@@ -633,7 +633,7 @@ func TestSetuidEtc(t *testing.T) {
                {call: "Setgid(1)", fn: func() error { return syscall.Setgid(1) }, filter: "Gid:", expect: "\t1\t1\t1\t1"},
                {call: "Setgid(0)", fn: func() error { return syscall.Setgid(0) }, filter: "Gid:", expect: "\t0\t0\t0\t0"},
 
-               {call: "Setgroups([]int{0,1,2,3})", fn: func() error { return syscall.Setgroups([]int{0, 1, 2, 3}) }, filter: "Groups:", expect: "\t0 1 2 3"},
+               {call: "Setgroups([]int{0,1,2,1000})", fn: func() error { return syscall.Setgroups([]int{0, 1, 2, 1000}) }, filter: "Groups:", expect: "\t0 1 2 1000"},
                {call: "Setgroups(nil)", fn: func() error { return syscall.Setgroups(nil) }, filter: "Groups:", expect: ""},
                {call: "Setgroups([]int{0})", fn: func() error { return syscall.Setgroups([]int{0}) }, filter: "Groups:", expect: "\t0"},
 

@AndrewGMorgan AndrewGMorgan changed the title syscall.TestSetuidEtc() assumes root (uid=0) should be able to run these tests syscall.TestSetuidEtc() fails in some container setups May 13, 2021
@gopherbot
Copy link

Change https://golang.org/cl/319591 mentions this issue: syscall: some containers may fail syscall.TestSetuidEtc

@AndrewGMorgan
Copy link
Contributor Author

I've changed the title to reflect the fact that the bounding set observation in the description of this bug was, in fact, a red herring.

@kusrinivasan
Copy link

I patched the additional test based on the fix-319591, I have applied the attached patch and all the tests passes on the container I am using.

85f8c99a38023c98448238f08668bfdfceca52f2-patch.txt

@golang golang locked and limited conversation to collaborators May 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants