From e599b5583dd821ed26bdfc01f7f67d4a317b9843 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 16 Feb 2025 17:26:09 +0900 Subject: fmsg: implement suspend in writer This removes the requirement to call fmsg.Exit on every exit path, and enables direct use of the "log" package. However, fmsg.BeforeExit is still encouraged when possible to catch exit on suspended output. Signed-off-by: Ophestra --- internal/app/init/early.go | 4 ++-- internal/app/init/main.go | 45 +++++++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'internal/app/init') diff --git a/internal/app/init/early.go b/internal/app/init/early.go index cc1c2f7e..ac2fedbf 100644 --- a/internal/app/init/early.go +++ b/internal/app/init/early.go @@ -4,7 +4,7 @@ import ( "os" "path" - "git.gensokyo.uk/security/fortify/internal/fmsg" + "git.gensokyo.uk/security/fortify/internal" ) // used by the parent process @@ -13,6 +13,6 @@ import ( func TryArgv0() { if len(os.Args) > 0 && path.Base(os.Args[0]) == "init" { Main() - fmsg.Exit(0) + internal.Exit(0) } } diff --git a/internal/app/init/main.go b/internal/app/init/main.go index 4c69312e..bf9ecbae 100644 --- a/internal/app/init/main.go +++ b/internal/app/init/main.go @@ -2,6 +2,7 @@ package init0 import ( "errors" + "log" "os" "os/exec" "os/signal" @@ -24,17 +25,15 @@ const ( func Main() { // sharing stdout with shim // USE WITH CAUTION - fmsg.SetPrefix("init") + fmsg.Prepare("init") // setting this prevents ptrace if err := internal.PR_SET_DUMPABLE__SUID_DUMP_DISABLE(); err != nil { - fmsg.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err) - panic("unreachable") + log.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err) } if os.Getpid() != 1 { - fmsg.Fatal("this process must run as pid 1") - panic("unreachable") + log.Fatal("this process must run as pid 1") } // receive setup payload @@ -44,30 +43,29 @@ func Main() { ) if f, err := proc.Receive(Env, &payload); err != nil { if errors.Is(err, proc.ErrInvalid) { - fmsg.Fatal("invalid config descriptor") + log.Fatal("invalid config descriptor") } if errors.Is(err, proc.ErrNotSet) { - fmsg.Fatal("FORTIFY_INIT not set") + log.Fatal("FORTIFY_INIT not set") } - fmsg.Fatalf("cannot decode init setup payload: %v", err) - panic("unreachable") + log.Fatalf("cannot decode init setup payload: %v", err) } else { - fmsg.SetVerbose(payload.Verbose) + fmsg.Store(payload.Verbose) closeSetup = f // child does not need to see this if err = os.Unsetenv(Env); err != nil { - fmsg.Printf("cannot unset %s: %v", Env, err) + log.Printf("cannot unset %s: %v", Env, err) // not fatal } else { - fmsg.VPrintln("received configuration") + fmsg.Verbose("received configuration") } } // die with parent if err := internal.PR_SET_PDEATHSIG__SIGKILL(); err != nil { - fmsg.Fatalf("prctl(PR_SET_PDEATHSIG, SIGKILL): %v", err) + log.Fatalf("prctl(PR_SET_PDEATHSIG, SIGKILL): %v", err) } cmd := exec.Command(payload.Argv0) @@ -76,13 +74,13 @@ func Main() { cmd.Env = os.Environ() if err := cmd.Start(); err != nil { - fmsg.Fatalf("cannot start %q: %v", payload.Argv0, err) + log.Fatalf("cannot start %q: %v", payload.Argv0, err) } fmsg.Suspend() // close setup pipe as setup is now complete if err := closeSetup(); err != nil { - fmsg.Println("cannot close setup pipe:", err) + log.Println("cannot close setup pipe:", err) // not fatal } @@ -119,7 +117,7 @@ func Main() { } } if !errors.Is(err, syscall.ECHILD) { - fmsg.Println("unexpected wait4 response:", err) + log.Println("unexpected wait4 response:", err) } close(done) @@ -132,9 +130,12 @@ func Main() { for { select { case s := <-sig: - fmsg.VPrintln("received", s.String()) - fmsg.Resume() // output could still be withheld at this point, so resume is called - fmsg.Exit(0) + if fmsg.Resume() { + fmsg.Verbosef("terminating on %s after process start", s.String()) + } else { + fmsg.Verbosef("terminating on %s", s.String()) + } + internal.Exit(0) case w := <-info: if w.wpid == cmd.Process.Pid { // initial process exited, output is most likely available again @@ -155,10 +156,10 @@ func Main() { }() } case <-done: - fmsg.Exit(r) + internal.Exit(r) case <-timeout: - fmsg.Println("timeout exceeded waiting for lingering processes") - fmsg.Exit(r) + log.Println("timeout exceeded waiting for lingering processes") + internal.Exit(r) } } } -- cgit v1.3.1