diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-10-22 06:55:02 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-10-22 06:58:45 +0900 |
| commit | 8accd3b2190d0527ec0d848c877b1a68abaac28c (patch) | |
| tree | 831d6ce88a4d461fd7c37165dbd1bb1549bf8092 /internal/app/dispatcher.go | |
| parent | c5f59c5488cc529a5a7c7a89e1da56c2b44db16c (diff) | |
internal/app/shim: use syscall dispatcher
This enables instrumented testing of the shim.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/dispatcher.go')
| -rw-r--r-- | internal/app/dispatcher.go | 71 |
1 files changed, 63 insertions, 8 deletions
diff --git a/internal/app/dispatcher.go b/internal/app/dispatcher.go index d298d6b6..b081ece1 100644 --- a/internal/app/dispatcher.go +++ b/internal/app/dispatcher.go @@ -1,16 +1,18 @@ package app import ( + "context" "io" "io/fs" - "log" "os" "os/exec" + "os/signal" "os/user" "path/filepath" "hakurei.app/container" "hakurei.app/container/check" + "hakurei.app/container/seccomp" "hakurei.app/internal" "hakurei.app/message" "hakurei.app/system/dbus" @@ -28,7 +30,7 @@ type syscallDispatcher interface { // new starts a goroutine with a new instance of syscallDispatcher. // A syscallDispatcher must never be used in any goroutine other than the one owning it, // just synchronising access is not enough, as this is for test instrumentation. - new(f func(k syscallDispatcher)) + new(f func(k syscallDispatcher, msg message.Msg)) // getpid provides [os.Getpid]. getpid() int @@ -38,6 +40,8 @@ type syscallDispatcher interface { getgid() int // lookupEnv provides [os.LookupEnv]. lookupEnv(key string) (string, bool) + // pipe provides os.Pipe. + pipe() (r, w *os.File, err error) // stat provides [os.Stat]. stat(name string) (os.FileInfo, error) // open provides [os.Open]. @@ -46,6 +50,8 @@ type syscallDispatcher interface { readdir(name string) ([]os.DirEntry, error) // tempdir provides [os.TempDir]. tempdir() string + // exit provides [os.Exit]. + exit(code int) // evalSymlinks provides [filepath.EvalSymlinks]. evalSymlinks(path string) (string, error) @@ -56,10 +62,29 @@ type syscallDispatcher interface { // cmdOutput provides the Output method of [exec.Cmd]. cmdOutput(cmd *exec.Cmd) ([]byte, error) + // notifyContext provides [signal.NotifyContext]. + notifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) + + // prctl provides [container.Prctl]. + prctl(op, arg2, arg3 uintptr) error // overflowUid provides [container.OverflowUid]. overflowUid(msg message.Msg) int // overflowGid provides [container.OverflowGid]. overflowGid(msg message.Msg) int + // setDumpable provides [container.SetDumpable]. + setDumpable(dumpable uintptr) error + // receive provides [container.Receive]. + receive(key string, e any, fdp *uintptr) (closeFunc func() error, err error) + + // containerStart provides the Start method of [container.Container]. + containerStart(z *container.Container) error + // containerStart provides the Serve method of [container.Container]. + containerServe(z *container.Container) error + // containerStart provides the Wait method of [container.Container]. + containerWait(z *container.Container) error + + // seccompLoad provides [seccomp.Load]. + seccompLoad(rules []seccomp.NativeRule, flags seccomp.ExportFlag) error // mustHsuPath provides [internal.MustHsuPath]. mustHsuPath() *check.Absolute @@ -67,23 +92,32 @@ type syscallDispatcher interface { // dbusAddress provides [dbus.Address]. dbusAddress() (session, system string) + // setupContSignal provides setupContSignal. + setupContSignal(pid int) (io.ReadCloser, func(), error) + + // getMsg returns the [message.Msg] held by syscallDispatcher. + getMsg() message.Msg + // fatal provides [log.Fatal]. + fatal(v ...any) // fatalf provides [log.Fatalf]. fatalf(format string, v ...any) } // direct implements syscallDispatcher on the current kernel. -type direct struct{} +type direct struct{ msg message.Msg } -func (k direct) new(f func(k syscallDispatcher)) { go f(k) } +func (k direct) new(f func(k syscallDispatcher, msg message.Msg)) { go f(k, k.msg) } func (direct) getpid() int { return os.Getpid() } func (direct) getuid() int { return os.Getuid() } func (direct) getgid() int { return os.Getgid() } func (direct) lookupEnv(key string) (string, bool) { return os.LookupEnv(key) } +func (direct) pipe() (r, w *os.File, err error) { return os.Pipe() } func (direct) stat(name string) (os.FileInfo, error) { return os.Stat(name) } func (direct) open(name string) (osFile, error) { return os.Open(name) } func (direct) readdir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) } func (direct) tempdir() string { return os.TempDir() } +func (direct) exit(code int) { os.Exit(code) } func (direct) evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) } @@ -98,11 +132,32 @@ func (direct) lookupGroupId(name string) (gid string, err error) { func (direct) cmdOutput(cmd *exec.Cmd) ([]byte, error) { return cmd.Output() } -func (direct) overflowUid(msg message.Msg) int { return container.OverflowUid(msg) } -func (direct) overflowGid(msg message.Msg) int { return container.OverflowGid(msg) } +func (direct) notifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) { + return signal.NotifyContext(parent, signals...) +} + +func (direct) prctl(op, arg2, arg3 uintptr) error { return container.Prctl(op, arg2, arg3) } +func (direct) overflowUid(msg message.Msg) int { return container.OverflowUid(msg) } +func (direct) overflowGid(msg message.Msg) int { return container.OverflowGid(msg) } +func (direct) setDumpable(dumpable uintptr) error { return container.SetDumpable(dumpable) } +func (direct) receive(key string, e any, fdp *uintptr) (func() error, error) { + return container.Receive(key, e, fdp) +} + +func (direct) containerStart(z *container.Container) error { return z.Start() } +func (direct) containerServe(z *container.Container) error { return z.Serve() } +func (direct) containerWait(z *container.Container) error { return z.Wait() } + +func (direct) seccompLoad(rules []seccomp.NativeRule, flags seccomp.ExportFlag) error { + return seccomp.Load(rules, flags) +} func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() } -func (k direct) dbusAddress() (session, system string) { return dbus.Address() } +func (direct) dbusAddress() (session, system string) { return dbus.Address() } + +func (direct) setupContSignal(pid int) (io.ReadCloser, func(), error) { return setupContSignal(pid) } -func (direct) fatalf(format string, v ...any) { log.Fatalf(format, v...) } +func (k direct) getMsg() message.Msg { return k.msg } +func (k direct) fatal(v ...any) { k.msg.GetLogger().Fatal(v...) } +func (k direct) fatalf(format string, v ...any) { k.msg.GetLogger().Fatalf(format, v...) } |
