diff options
| author | Andrew G. Morgan <agm@google.com> | 2020-10-28 13:35:57 -0700 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2020-10-29 17:53:57 +0000 |
| commit | 3a819e8998af1db3bdd34eb2ab059a3c534c6def (patch) | |
| tree | 8fd6d218b9b85f82dab1ada0c9ca9699ba0ee6b0 /src/syscall/syscall_linux_test.go | |
| parent | 4fb429138881e3fe171e4c2e958ed0da26ddfd9c (diff) | |
| download | go-3a819e8998af1db3bdd34eb2ab059a3c534c6def.tar.xz | |
syscall: handle undefined r2 value on linux-ppc64x
This change fixes two failng tests on linux-ppc64x:
- TestAllThreadsSyscall() exposed a real bug in the ppc64x support:
- It turns out that the r2 syscall return value is not defined
on all architectures. Notably linux-ppc64x so address that by
introducing a private architectural constant in the syscall
package, archHonorsR2: true if r2 has a determanistic value.
- TestSetuidEtc() was sensitive to /proc/<PID>/status content:
- The amount of padding space has changed with kernel vintage.
- Stress testing revealed a race with /proc files disappearing.
Fixes #42178
Change-Id: Ie6fc0b8f2f94a409ac0e5756e73bfce113274709
Reviewed-on: https://go-review.googlesource.com/c/go/+/266202
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'src/syscall/syscall_linux_test.go')
| -rw-r--r-- | src/syscall/syscall_linux_test.go | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go index 0742ef5b07..41ae8cc5a1 100644 --- a/src/syscall/syscall_linux_test.go +++ b/src/syscall/syscall_linux_test.go @@ -410,9 +410,6 @@ const ( // syscalls that execute on all OSThreads - with which to support // POSIX semantics for security state changes. func TestAllThreadsSyscall(t *testing.T) { - if runtime.GOARCH == "ppc64" { - t.Skip("skipping on linux/ppc64; see issue #42178") - } if _, _, err := syscall.AllThreadsSyscall(syscall.SYS_PRCTL, PR_SET_KEEPCAPS, 0, 0); err == syscall.ENOTSUP { t.Skip("AllThreadsSyscall disabled with cgo") } @@ -544,7 +541,7 @@ func TestAllThreadsSyscall(t *testing.T) { // compareStatus is used to confirm the contents of the thread // specific status files match expectations. func compareStatus(filter, expect string) error { - expected := filter + "\t" + expect + expected := filter + expect pid := syscall.Getpid() fs, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/task", pid)) if err != nil { @@ -553,14 +550,22 @@ func compareStatus(filter, expect string) error { for _, f := range fs { tf := fmt.Sprintf("/proc/%s/status", f.Name()) d, err := ioutil.ReadFile(tf) + if os.IsNotExist(err) { + // We are racing against threads dying, which + // is out of our control, so ignore the + // missing file and skip to the next one. + continue + } if err != nil { return fmt.Errorf("unable to read %q: %v", tf, err) } lines := strings.Split(string(d), "\n") for _, line := range lines { + // Different kernel vintages pad differently. + line = strings.TrimSpace(line) if strings.HasPrefix(line, filter) { if line != expected { - return fmt.Errorf("%s %s (bad)\n", tf, line) + return fmt.Errorf("%q got:%q want:%q (bad)\n", tf, line, expected) } break } @@ -580,9 +585,6 @@ func compareStatus(filter, expect string) error { // the syscalls. Care should be taken to mirror any enhancements to // this test here in that file too. func TestSetuidEtc(t *testing.T) { - if runtime.GOARCH == "ppc64" { - t.Skip("skipping on linux/ppc64; see issue #42178") - } if syscall.Getuid() != 0 { t.Skip("skipping root only test") } @@ -591,34 +593,34 @@ func TestSetuidEtc(t *testing.T) { fn func() error filter, expect string }{ - {call: "Setegid(1)", fn: func() error { return syscall.Setegid(1) }, filter: "Gid:", expect: "0\t1\t0\t1"}, - {call: "Setegid(0)", fn: func() error { return syscall.Setegid(0) }, filter: "Gid:", expect: "0\t0\t0\t0"}, + {call: "Setegid(1)", fn: func() error { return syscall.Setegid(1) }, filter: "Gid:", expect: "\t0\t1\t0\t1"}, + {call: "Setegid(0)", fn: func() error { return syscall.Setegid(0) }, filter: "Gid:", expect: "\t0\t0\t0\t0"}, - {call: "Seteuid(1)", fn: func() error { return syscall.Seteuid(1) }, filter: "Uid:", expect: "0\t1\t0\t1"}, - {call: "Setuid(0)", fn: func() error { return syscall.Setuid(0) }, filter: "Uid:", expect: "0\t0\t0\t0"}, + {call: "Seteuid(1)", fn: func() error { return syscall.Seteuid(1) }, filter: "Uid:", expect: "\t0\t1\t0\t1"}, + {call: "Setuid(0)", fn: func() error { return syscall.Setuid(0) }, filter: "Uid:", expect: "\t0\t0\t0\t0"}, - {call: "Setgid(1)", fn: func() error { return syscall.Setgid(1) }, filter: "Gid:", expect: "1\t1\t1\t1"}, - {call: "Setgid(0)", fn: func() error { return syscall.Setgid(0) }, filter: "Gid:", expect: "0\t0\t0\t0"}, + {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: "0 1 2 3 "}, - {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: "0 "}, + {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(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"}, - {call: "Setregid(101,0)", fn: func() error { return syscall.Setregid(101, 0) }, filter: "Gid:", expect: "101\t0\t0\t0"}, - {call: "Setregid(0,102)", fn: func() error { return syscall.Setregid(0, 102) }, filter: "Gid:", expect: "0\t102\t102\t102"}, - {call: "Setregid(0,0)", fn: func() error { return syscall.Setregid(0, 0) }, filter: "Gid:", expect: "0\t0\t0\t0"}, + {call: "Setregid(101,0)", fn: func() error { return syscall.Setregid(101, 0) }, filter: "Gid:", expect: "\t101\t0\t0\t0"}, + {call: "Setregid(0,102)", fn: func() error { return syscall.Setregid(0, 102) }, filter: "Gid:", expect: "\t0\t102\t102\t102"}, + {call: "Setregid(0,0)", fn: func() error { return syscall.Setregid(0, 0) }, filter: "Gid:", expect: "\t0\t0\t0\t0"}, - {call: "Setreuid(1,0)", fn: func() error { return syscall.Setreuid(1, 0) }, filter: "Uid:", expect: "1\t0\t0\t0"}, - {call: "Setreuid(0,2)", fn: func() error { return syscall.Setreuid(0, 2) }, filter: "Uid:", expect: "0\t2\t2\t2"}, - {call: "Setreuid(0,0)", fn: func() error { return syscall.Setreuid(0, 0) }, filter: "Uid:", expect: "0\t0\t0\t0"}, + {call: "Setreuid(1,0)", fn: func() error { return syscall.Setreuid(1, 0) }, filter: "Uid:", expect: "\t1\t0\t0\t0"}, + {call: "Setreuid(0,2)", fn: func() error { return syscall.Setreuid(0, 2) }, filter: "Uid:", expect: "\t0\t2\t2\t2"}, + {call: "Setreuid(0,0)", fn: func() error { return syscall.Setreuid(0, 0) }, filter: "Uid:", expect: "\t0\t0\t0\t0"}, - {call: "Setresgid(101,0,102)", fn: func() error { return syscall.Setresgid(101, 0, 102) }, filter: "Gid:", expect: "101\t0\t102\t0"}, - {call: "Setresgid(0,102,101)", fn: func() error { return syscall.Setresgid(0, 102, 101) }, filter: "Gid:", expect: "0\t102\t101\t102"}, - {call: "Setresgid(0,0,0)", fn: func() error { return syscall.Setresgid(0, 0, 0) }, filter: "Gid:", expect: "0\t0\t0\t0"}, + {call: "Setresgid(101,0,102)", fn: func() error { return syscall.Setresgid(101, 0, 102) }, filter: "Gid:", expect: "\t101\t0\t102\t0"}, + {call: "Setresgid(0,102,101)", fn: func() error { return syscall.Setresgid(0, 102, 101) }, filter: "Gid:", expect: "\t0\t102\t101\t102"}, + {call: "Setresgid(0,0,0)", fn: func() error { return syscall.Setresgid(0, 0, 0) }, filter: "Gid:", expect: "\t0\t0\t0\t0"}, - {call: "Setresuid(1,0,2)", fn: func() error { return syscall.Setresuid(1, 0, 2) }, filter: "Uid:", expect: "1\t0\t2\t0"}, - {call: "Setresuid(0,2,1)", fn: func() error { return syscall.Setresuid(0, 2, 1) }, filter: "Uid:", expect: "0\t2\t1\t2"}, - {call: "Setresuid(0,0,0)", fn: func() error { return syscall.Setresuid(0, 0, 0) }, filter: "Uid:", expect: "0\t0\t0\t0"}, + {call: "Setresuid(1,0,2)", fn: func() error { return syscall.Setresuid(1, 0, 2) }, filter: "Uid:", expect: "\t1\t0\t2\t0"}, + {call: "Setresuid(0,2,1)", fn: func() error { return syscall.Setresuid(0, 2, 1) }, filter: "Uid:", expect: "\t0\t2\t1\t2"}, + {call: "Setresuid(0,0,0)", fn: func() error { return syscall.Setresuid(0, 0, 0) }, filter: "Uid:", expect: "\t0\t0\t0\t0"}, } for i, v := range vs { |
