diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go index e369d0f..61a091d 100644 --- a/container/dispatcher_test.go +++ b/container/dispatcher_test.go @@ -3,7 +3,6 @@ package container import ( "bytes" "errors" - "fmt" "io" "io/fs" "os" @@ -114,6 +113,7 @@ type simpleTestCase struct { func checkSimple(t *testing.T, fname string, testCases []simpleTestCase) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + defer handleExitStub(t, "check") k := &kstub{t: t, want: tc.want, wg: new(sync.WaitGroup)} if err := tc.f(k); !errors.Is(err, tc.wantErr) { t.Errorf("%s: error = %v, want %v", fname, err, tc.wantErr) @@ -170,6 +170,8 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { }) } +func sliceAddr[S any](s []S) *[]S { return &s } + func newCheckedFile(t *testing.T, name, wantData string, closeErr error) osFile { f := &checkedOsFile{t: t, name: name, want: wantData, closeErr: closeErr} // check happens in Close, and cleanup is not guaranteed to run, so relying on it for sloppy implementations will cause sporadic test results @@ -263,6 +265,17 @@ func (k *kexpect) error(ok ...bool) error { return syscall.ENOTRECOVERABLE } +func handleExitStub(t *testing.T, prefix string) { + r := recover() + if r == 0xdeadbeef { + t.Log(prefix + " terminated on an exit stub") + return + } + if r != nil { + panic(r) + } +} + type kstub struct { t *testing.T @@ -344,7 +357,11 @@ func (k *kstub) new(f func(k syscallDispatcher)) { sk := &kstub{t: k.t, want: k.want, track: len(k.sub) + 1, wg: k.wg} k.sub = append(k.sub, sk) k.wg.Add(1) - go func() { defer k.wg.Done(); f(sk) }() + go func() { + defer k.wg.Done() + defer handleExitStub(k.t, "goroutine") + f(sk) + }() } func (k *kstub) lockOSThread() { k.expect("lockOSThread") } @@ -390,10 +407,45 @@ func (k *kstub) isatty(fd int) bool { func (k *kstub) receive(key string, e any, fdp *uintptr) (closeFunc func() error, err error) { expect := k.expect("receive") - return expect.ret.(func() error), expect.error( + + var closed bool + closeFunc = func() error { + if closed { + k.t.Error("closeFunc called more than once") + return os.ErrClosed + } + closed = true + + if expect.ret != nil { + // use return stored in kexpect for closeFunc instead + return expect.ret.(error) + } + return nil + } + err = expect.error( checkArg(k, "key", key, 0), checkArgReflect(k, "e", e, 1), - checkArg(k, "fdp", fdp, 2)) + checkArgReflect(k, "fdp", fdp, 2)) + + // 3 is unused so stores params + if expect.args[3] != nil { + if v, ok := expect.args[3].(*initParams); ok && v != nil { + if p, ok0 := e.(*initParams); ok0 && p != nil { + *p = *v + } + } + } + + // 4 is unused so stores fd + if expect.args[4] != nil { + if v, ok := expect.args[4].(uintptr); ok && v >= 3 { + if fdp != nil { + *fdp = v + } + } + } + + return } func (k *kstub) bindMount(source, target string, flags uintptr, eq bool) error { @@ -441,20 +493,23 @@ func (k *kstub) notify(c chan<- os.Signal, sig ...os.Signal) { } // export channel for external instrumentation - if chanp, ok := expect.args[0].(*chan<- os.Signal); ok && chanp != nil { - if *chanp != nil { - panic(fmt.Sprintf("attempting reuse of %p", chanp)) - } - *chanp = c + if chanf, ok := expect.args[0].(func(c chan<- os.Signal)); ok && chanf != nil { + chanf(c) } } func (k *kstub) start(c *exec.Cmd) error { - return k.expect("start").error( + expect := k.expect("start") + err := expect.error( checkArg(k, "c.Path", c.Path, 0), checkArgReflect(k, "c.Args", c.Args, 1), checkArgReflect(k, "c.Env", c.Env, 2), checkArg(k, "c.Dir", c.Dir, 3)) + + if process, ok := expect.ret.(*os.Process); ok && process != nil { + c.Process = process + } + return err } func (k *kstub) signal(c *exec.Cmd, sig os.Signal) error { @@ -477,6 +532,7 @@ func (k *kstub) exit(code int) { if !checkArg(k, "code", code, 0) { k.t.FailNow() } + panic(0xdeadbeef) } func (k *kstub) getpid() int { return k.expect("getpid").ret.(int) } @@ -618,11 +674,25 @@ func (k *kstub) unmount(target string, flags int) (err error) { func (k *kstub) wait4(pid int, wstatus *syscall.WaitStatus, options int, rusage *syscall.Rusage) (wpid int, err error) { expect := k.expect("wait4") - return expect.ret.(int), expect.error( + // special case to prevent leaking the wait4 goroutine when testing initEntrypoint + if v, ok := expect.args[4].(int); ok && v == 0xdeadbeef { + k.t.Log("terminating current goroutine as requested by kexpect") + panic(0xdeadbeef) + } + + wpid = expect.ret.(int) + err = expect.error( checkArg(k, "pid", pid, 0), - checkArg(k, "wstatus", wstatus, 1), - checkArg(k, "options", options, 2), - checkArg(k, "rusage", rusage, 3)) + checkArg(k, "options", options, 2)) + + if wstatusV, ok := expect.args[1].(syscall.WaitStatus); wstatus != nil && ok { + *wstatus = wstatusV + } + if rusageV, ok := expect.args[3].(syscall.Rusage); rusage != nil && ok { + *rusage = rusageV + } + + return } func (k *kstub) printf(format string, v ...any) { @@ -638,6 +708,7 @@ func (k *kstub) fatal(v ...any) { checkArgReflect(k, "v", v, 0)) != nil { k.t.FailNow() } + panic(0xdeadbeef) } func (k *kstub) fatalf(format string, v ...any) { @@ -646,6 +717,7 @@ func (k *kstub) fatalf(format string, v ...any) { checkArgReflect(k, "v", v, 1)) != nil { k.t.FailNow() } + panic(0xdeadbeef) } func (k *kstub) verbose(v ...any) { diff --git a/container/init.go b/container/init.go index 44e89c7..a13a523 100644 --- a/container/init.go +++ b/container/init.go @@ -127,7 +127,7 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV // write uid/gid map here so parent does not need to set dumpable if err := k.setDumpable(SUID_DUMP_USER); err != nil { - k.fatalf("cannot set SUID_DUMP_USER: %s", err) + k.fatalf("cannot set SUID_DUMP_USER: %v", err) } if err := k.writeFile(FHSProc+"self/uid_map", append([]byte{}, strconv.Itoa(params.Uid)+" "+strconv.Itoa(params.HostUid)+" 1\n"...), @@ -145,7 +145,7 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV k.fatalf("%v", err) } if err := k.setDumpable(SUID_DUMP_DISABLE); err != nil { - k.fatalf("cannot set SUID_DUMP_DISABLE: %s", err) + k.fatalf("cannot set SUID_DUMP_DISABLE: %v", err) } oldmask := k.umask(0) @@ -178,7 +178,6 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV fmt.Sprintf("cannot prepare op at index %d:", i)) k.beforeExit() k.exit(1) - return } } @@ -219,7 +218,6 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV fmt.Sprintf("cannot apply op at index %d:", i)) k.beforeExit() k.exit(1) - return } } @@ -250,7 +248,7 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV k.fatalf("cannot re-enter intermediate root: %v", err) } if err := k.unmount(".", MNT_DETACH); err != nil { - k.fatalf("cannot unmount intemediate root: %v", err) + k.fatalf("cannot unmount intermediate root: %v", err) } if err := k.chdir(FHSRoot); err != nil { k.fatalf("cannot enter root: %v", err) @@ -389,7 +387,6 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV } k.beforeExit() k.exit(0) - return case w := <-info: if w.wpid == cmd.Process.Pid { @@ -416,13 +413,11 @@ func initEntrypoint(k syscallDispatcher, prepareLogger func(prefix string), setV case <-done: k.beforeExit() k.exit(r) - return case <-timeout: k.printf("timeout exceeded waiting for lingering processes") k.beforeExit() k.exit(r) - return } } } diff --git a/container/init_test.go b/container/init_test.go new file mode 100644 index 0000000..de165da --- /dev/null +++ b/container/init_test.go @@ -0,0 +1,2539 @@ +package container + +import ( + "os" + "syscall" + "testing" + "time" + + "hakurei.app/container/seccomp" +) + +func TestInitEntrypoint(t *testing.T) { + assertPrefix := func(prefix string) { + if prefix != "init" { + t.Fatalf("prepareLogger: prefix = %q", prefix) + } + } + + assertVerboseFalse := func(verbose bool) { + if verbose { + t.Fatal("setVerbose: verbose = true, want false") + } + } + assertVerboseTrue := func(verbose bool) { + if !verbose { + t.Fatal("setVerbose: verbose = false, want true") + } + } + + checkSimple(t, "initEntrypoint", []simpleTestCase{ + {"getpid", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1 << 10, nil}, + {"fatal", expectArgs{[]any{"this process must run as pid 1"}}, nil, nil}, + }, + }, nil}, + + {"receive bad fd", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, syscall.EBADF}, + {"fatal", expectArgs{[]any{"invalid setup descriptor"}}, nil, nil}, + }, + }, nil}, + + {"receive not set", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, ErrNotSet}, + {"fatal", expectArgs{[]any{"HAKUREI_SETUP not set"}}, nil, nil}, + }, + }, nil}, + + {"receive payload decode", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot decode init setup payload: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"receive invalid params", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"fatal", expectArgs{[]any{"invalid setup parameters"}}, nil, nil}, + }, + }, nil}, + + {"setDumpable user", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot set SUID_DUMP_USER: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"writeFile uid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"writeFile setgroups", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"writeFile gid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"setDumpable disable", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot set SUID_DUMP_DISABLE: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"sethostname", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, errUnique}, + {"fatalf", expectArgs{"cannot set hostname: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"mount rslave root", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, errUnique}, + {"fatalf", expectArgs{"cannot make / rslave: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"nil op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: (*Ops)(sliceAddr(make(Ops, 1))), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"fatalf", expectArgs{"invalid op at index %d", []any{0}}, nil, nil}, + /* end early */ + }, + }, nil}, + + {"invalid op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(nil, nil, BindDevice), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"fatalf", expectArgs{"invalid op at index %d", []any{0}}, nil, nil}, + /* end early */ + }, + }, nil}, + + {"apply", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", errUnique}, + {"printBaseErr", expectArgs{wrapErrSelf(errUnique), "cannot prepare op at index 0:"}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{1}, nil, nil}, + /* end early */ + }, + }, nil}, + + {"mount ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, errUnique}, + {"fatalf", expectArgs{"cannot mount intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"chdir ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, errUnique}, + {"fatalf", expectArgs{"cannot enter intermediate host path: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"mkdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"mount bind sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, errUnique}, + {"fatalf", expectArgs{"cannot bind sysroot: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"mkdir host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"pivotRoot ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, errUnique}, + {"fatalf", expectArgs{"cannot pivot into intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, errUnique}, + {"fatalf", expectArgs{"cannot enter intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"apply", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, errUnique}, + {"printBaseErr", expectArgs{wrapErrSuffix(errUnique, `cannot mount proc on "/proc/":`), "cannot apply op at index 1:"}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{1}, nil, nil}, + /* end apply */ + }, + }, nil}, + + {"mount rprivate host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, errUnique}, + {"fatalf", expectArgs{"cannot make host root rprivate: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"unmount host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, errUnique}, + {"fatalf", expectArgs{"cannot unmount host root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"open ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, errUnique}, + {"fatalf", expectArgs{"cannot open intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"chdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, errUnique}, + {"fatalf", expectArgs{"cannot enter sysroot: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"pivotRoot sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, errUnique}, + {"fatalf", expectArgs{"cannot pivot into sysroot: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"fchdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, errUnique}, + {"fatalf", expectArgs{"cannot re-enter intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"unmount ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, errUnique}, + {"fatalf", expectArgs{"cannot unmount intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, errUnique}, + {"fatalf", expectArgs{"cannot enter root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"close ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, errUnique}, + {"fatalf", expectArgs{"cannot close intermediate root: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"capAmbientClearAll", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, errUnique}, + {"fatalf", expectArgs{"cannot clear the ambient capability set: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"capBoundingSetDrop", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot drop capability from bounding set: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"capAmbientRaise", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot raise CAP_SYS_ADMIN: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"capset", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, errUnique}, + {"fatalf", expectArgs{"cannot capset: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"seccompLoad", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, + {"verbosef", expectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, + {"seccompLoad", expectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, errUnique}, + {"fatalf", expectArgs{"cannot load syscall filter: %v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"start", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x15)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, errUnique}, + {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, + }, nil}, + + {"lowlastcap signaled cancel forward error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Nanosecond, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(4), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, true, nil}, + {"verbosef", expectArgs{"%s after process start", []any{"terminated"}}, nil, nil}, + {"verbose", expectArgs{[]any{"forwarding context cancellation"}}, nil, nil}, + {"signal", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, nil, errUnique}, + {"printf", expectArgs{"cannot forward cancellation: %v", []any{errUnique}}, nil, nil}, + {"resume", expectArgs{}, false, nil}, + {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"printf", expectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{0xce}, nil, nil}, + }, + + /* wait4 */ + { + {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour + {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }, + }, nil}, + + {"lowlastcap signaled cancel", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Nanosecond, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(4), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, false, nil}, + {"verbosef", expectArgs{"got %s", []any{"interrupt"}}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{0}, nil, nil}, + }, + + /* wait4 */ + { + // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour + {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }, + }, nil}, + + {"lowlastcap signaled timeout", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Nanosecond, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(4), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, true, nil}, + {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"printf", expectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{0xce}, nil, nil}, + }, + + /* wait4 */ + { + {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour + {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }, + }, nil}, + + {"lowlastcap signaled", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(4), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, true, nil}, + {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{0xce}, nil, nil}, + }, + + /* wait4 */ + { + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, + {"printf", expectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, + }, + }, nil}, + + {"strangewait nopriv notty noseccomp yamafault", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, + {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei/nonexistent"), + Path: MustAbs("/run/current-system/sw/bin/bash"), + Args: []string{"bash", "-c", "false"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 24, + Gid: 1 << 47, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompDisable: true, + ParentPerm: 0750, + }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x15)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, true, nil}, + {"verbosef", expectArgs{"initial process exited with code %d", []any{1}}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{1}, nil, nil}, + }, + + /* wait4 */ + { + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade0100), 0, nil}, 0xbad, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, + {"printf", expectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, + }, + }, nil}, + + {"success", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + /* entrypoint */ + { + {"lockOSThread", expectArgs{}, nil, nil}, + {"getpid", expectArgs{}, 1, nil}, + {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, + {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Dir: MustAbs("/.hakurei"), + Env: []string{"DISPLAY=:0"}, + Path: MustAbs("/bin/zsh"), + Args: []string{"zsh", "-c", "exec vim"}, + ForwardCancel: true, + AdoptWaitDelay: 5 * time.Second, + Uid: 1 << 32, + Gid: 1 << 31, + Hostname: "hakurei-check", + Ops: new(Ops).Bind(MustAbs("/"), MustAbs("/"), BindDevice).Proc(MustAbs("/proc/")), + SeccompRules: make([]seccomp.NativeRule, 0), + SeccompPresets: seccomp.PresetStrict, + RetainSession: true, + Privileged: true, + }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, + {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, + {"umask", expectArgs{0}, 022, nil}, + {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", expectArgs{}, uintptr(40), nil}, + {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + /* begin early */ + {"evalSymlinks", expectArgs{"/"}, "/", nil}, + /* end early */ + {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + /* begin apply */ + {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", expectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + /* end apply */ + {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", expectArgs{"host", 2}, nil, nil}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", expectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", expectArgs{".", "."}, nil, nil}, + {"fchdir", expectArgs{1 << 35}, nil, nil}, + {"unmount", expectArgs{".", 2}, nil, nil}, + {"chdir", expectArgs{"/"}, nil, nil}, + {"close", expectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", expectArgs{}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, + {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, + {"verbosef", expectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, + {"seccompLoad", expectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, nil}, + {"verbosef", expectArgs{"%d filter rules loaded", []any{73}}, nil, nil}, + {"newFile", expectArgs{uintptr(10), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil}, + {"newFile", expectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil}, + {"umask", expectArgs{022}, 0, nil}, + {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/bin/zsh")}}, nil, nil}, + {"start", expectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil}, + {"suspend", expectArgs{}, nil, nil}, + {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, + {"new", expectArgs{}, nil, nil}, + {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", expectArgs{}, true, nil}, + {"verbosef", expectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil}, + {"beforeExit", expectArgs{}, nil, nil}, + {"exit", expectArgs{0xff}, nil, nil}, + }, + + /* wait4 */ + { + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade007f), 0, nil}, 0xcafe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ECHILD}, + }, + }, nil}, + }) +} + +func TestOpsGrow(t *testing.T) { + ops := new(Ops) + ops.Grow(1 << 4) + if got := cap(*ops); got == 0 { + t.Error("Grow: cap did not increase") + } +}