import (
"bytes"
- "errors"
"flag"
"fmt"
"internal/testenv"
"io"
- "io/fs"
"os"
"os/exec"
"os/user"
"unsafe"
)
-// isNotSupported reports whether err may indicate that a system call is
-// not supported by the current platform or execution environment.
-func isNotSupported(err error) bool {
- if err == nil {
- return false
- }
-
- var errno syscall.Errno
- if errors.As(err, &errno) {
- switch errno {
- case syscall.ENOSYS, syscall.ENOTSUP:
- // Explicitly not supported.
- // TODO(#41198): remove these cases when errors.Is reports that they are
- // equivalent to ErrUnsupported.
- return true
- case syscall.EPERM, syscall.EROFS:
- // User lacks permission: either the call requires root permission and the
- // user is not root, or the call is denied by a container security policy.
- return true
- case syscall.EINVAL:
- // Some containers return EINVAL instead of EPERM if a system call is
- // denied by security policy.
- return true
- }
- }
-
- if errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported) {
- return true
- }
-
- return false
-}
-
// whoamiNEWUSER returns a command that runs "whoami" with CLONE_NEWUSER,
// mapping uid and gid 0 to the actual uid and gid of the test.
func whoamiNEWUSER(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
if err == nil {
t.Skipf("unexpected success: probably old kernel without security fix?")
}
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: CLONE_NEWUSER appears to be unsupported")
}
t.Fatalf("got non-permission error") // Already logged above.
}
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
// May be inside a container that disallows CLONE_NEWUSER.
t.Skipf("skipping: CLONE_NEWUSER appears to be unsupported")
}
cmd := whoamiNEWUSER(t, os.Getuid(), os.Getgid(), false)
cmd.SysProcAttr.Credential = &syscall.Credential{}
if err := cmd.Run(); err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: %v: %v", cmd, err)
}
t.Fatal(err)
}
out, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
// CLONE_NEWNET does not appear to be supported.
t.Skipf("skipping due to permission error: %v", err)
}
}
out, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: %v: %v", cmd, err)
}
t.Fatalf("Cmd failed with err %v, output: %s", err, out)
}
out, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: %v: %v", cmd, err)
}
t.Fatalf("Cmd failed with err %v, output: %s", err, out)
o, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: could not start process with CLONE_NEWNS: %v", err)
}
t.Fatalf("unshare failed: %v\n%s", err, o)
o, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: could not start process with CLONE_NEWNS and Chroot %q: %v", d, err)
}
t.Fatalf("unshare failed: %v\n%s", err, o)
}
out, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: could not start process with CLONE_NEWNS and CLONE_NEWUSER: %v", err)
}
t.Fatalf("Cmd failed with err %v, output: %s", err, out)
CgroupFD: -1,
},
})
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("clone3 with CLONE_INTO_CGROUP not available: %v", err)
}
if err != nil {
// ErrPermission or EROFS (#57262) when running in an unprivileged container.
// ErrNotExist when cgroupfs is not mounted in chroot/schroot.
- if os.IsNotExist(err) || isNotSupported(err) {
+ if os.IsNotExist(err) || testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: %v", err)
}
t.Fatal(err)
}
out, err := cmd.CombinedOutput()
if err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
// CLONE_NEWTIME does not appear to be supported.
t.Skipf("skipping, CLONE_NEWTIME not supported: %v", err)
}
}
}
if err := cmd.Run(); err != nil {
- if isNotSupported(err) {
+ if testenv.SyscallIsNotSupported(err) {
t.Skipf("skipping: %v: %v", cmd, err)
}
t.Fatal(err.Error())