From b31d055e2087f95cb6172a67d8339a16d72987d3 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 18 Jan 2025 12:23:07 +0900 Subject: [PATCH] proc/priv/init: early init check Signed-off-by: Ophestra --- internal/proc/priv/init/early.go | 18 ++++++++++++++++++ internal/proc/priv/init/main.go | 9 --------- internal/proc/priv/shim/main.go | 15 +++++++++------ main.go | 3 +++ 4 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 internal/proc/priv/init/early.go diff --git a/internal/proc/priv/init/early.go b/internal/proc/priv/init/early.go new file mode 100644 index 0000000..cc1c2f7 --- /dev/null +++ b/internal/proc/priv/init/early.go @@ -0,0 +1,18 @@ +package init0 + +import ( + "os" + "path" + + "git.gensokyo.uk/security/fortify/internal/fmsg" +) + +// used by the parent process + +// TryArgv0 calls [Main] if argv0 indicates the process is started from a file named "init". +func TryArgv0() { + if len(os.Args) > 0 && path.Base(os.Args[0]) == "init" { + Main() + fmsg.Exit(0) + } +} diff --git a/internal/proc/priv/init/main.go b/internal/proc/priv/init/main.go index f32fada..d9f57b3 100644 --- a/internal/proc/priv/init/main.go +++ b/internal/proc/priv/init/main.go @@ -5,7 +5,6 @@ import ( "os" "os/exec" "os/signal" - "path" "syscall" "time" @@ -38,14 +37,6 @@ func Main() { panic("unreachable") } - // re-exec - if len(os.Args) > 0 && (os.Args[0] != "fortify" || os.Args[1] != "init" || len(os.Args) != 2) && path.IsAbs(os.Args[0]) { - if err := syscall.Exec(os.Args[0], []string{"fortify", "init"}, os.Environ()); err != nil { - fmsg.Println("cannot re-exec self:", err) - // continue anyway - } - } - // receive setup payload var ( payload Payload diff --git a/internal/proc/priv/shim/main.go b/internal/proc/priv/shim/main.go index 3ade286..85a425b 100644 --- a/internal/proc/priv/shim/main.go +++ b/internal/proc/priv/shim/main.go @@ -125,14 +125,17 @@ func Main() { } // bind fortify inside sandbox - innerSbin := path.Join(fst.Tmp, "sbin") - fortifyInnerPath := path.Join(innerSbin, "fortify") - conf.Bind(proc.MustExecutable(), fortifyInnerPath) - conf.Symlink(fortifyInnerPath, path.Join(innerSbin, "init")) + var ( + innerSbin = path.Join(fst.Tmp, "sbin") + innerFortify = path.Join(innerSbin, "fortify") + innerInit = path.Join(innerSbin, "init") + ) + conf.Bind(proc.MustExecutable(), innerFortify) + conf.Symlink("fortify", innerInit) helper.BubblewrapName = payload.Exec[0] // resolved bwrap path by parent - if b, err := helper.NewBwrap(conf, nil, fortifyInnerPath, - func(int, int) []string { return []string{"init"} }); err != nil { + if b, err := helper.NewBwrap(conf, nil, innerInit, + func(int, int) []string { return make([]string, 0) }); err != nil { fmsg.Fatalf("malformed sandbox config: %v", err) } else { cmd := b.Unwrap() diff --git a/main.go b/main.go index bb93f8f..e6e856b 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,9 @@ func (g *gl) Set(v string) error { } func main() { + // early init argv0 check, skips root check and duplicate PR_SET_DUMPABLE + init0.TryArgv0() + if err := internal.PR_SET_DUMPABLE__SUID_DUMP_DISABLE(); err != nil { fmsg.Printf("cannot set SUID_DUMP_DISABLE: %s", err) // not fatal: this program runs as the privileged user