Compare commits

..

2 Commits

Author SHA1 Message Date
f69e8e753e
cmd/finit: switch to generic receive func
All checks were successful
Tests / Go tests (push) Successful in 38s
Nix / NixOS tests (push) Successful in 5m40s
Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
2024-12-18 16:49:19 +09:00
ef8fd37e9d
proc: setup payload receive
Generic implementation of setup payload receiver adapted from finit.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
2024-12-18 16:48:41 +09:00
2 changed files with 47 additions and 22 deletions

View File

@ -1,19 +1,18 @@
package main package main
import ( import (
"encoding/gob"
"errors" "errors"
"os" "os"
"os/exec" "os/exec"
"os/signal" "os/signal"
"path" "path"
"strconv"
"syscall" "syscall"
"time" "time"
init0 "git.ophivana.moe/security/fortify/cmd/finit/ipc" init0 "git.ophivana.moe/security/fortify/cmd/finit/ipc"
"git.ophivana.moe/security/fortify/internal" "git.ophivana.moe/security/fortify/internal"
"git.ophivana.moe/security/fortify/internal/fmsg" "git.ophivana.moe/security/fortify/internal/fmsg"
"git.ophivana.moe/security/fortify/internal/proc"
) )
const ( const (
@ -48,30 +47,24 @@ func main() {
} }
} }
// setup pipe fd from environment // receive setup payload
var setup *os.File var (
if s, ok := os.LookupEnv(init0.Env); !ok { payload init0.Payload
fmsg.Fatal("FORTIFY_INIT not set") closeSetup func() error
panic("unreachable") )
} else { if f, err := proc.Receive(init0.Env, &payload); err != nil {
if fd, err := strconv.Atoi(s); err != nil { if errors.Is(err, proc.ErrInvalid) {
fmsg.Fatalf("cannot parse %q: %v", s, err)
panic("unreachable")
} else {
setup = os.NewFile(uintptr(fd), "setup")
if setup == nil {
fmsg.Fatal("invalid config descriptor") fmsg.Fatal("invalid config descriptor")
panic("unreachable")
}
} }
if errors.Is(err, proc.ErrNotSet) {
fmsg.Fatal("FORTIFY_INIT not set")
} }
var payload init0.Payload fmsg.Fatalf("cannot decode init setup payload: %v", err)
if err := gob.NewDecoder(setup).Decode(&payload); err != nil {
fmsg.Fatal("cannot decode init setup payload:", err)
panic("unreachable") panic("unreachable")
} else { } else {
fmsg.SetVerbose(payload.Verbose) fmsg.SetVerbose(payload.Verbose)
closeSetup = f
// child does not need to see this // child does not need to see this
if err = os.Unsetenv(init0.Env); err != nil { if err = os.Unsetenv(init0.Env); err != nil {
@ -98,7 +91,7 @@ func main() {
fmsg.Suspend() fmsg.Suspend()
// close setup pipe as setup is now complete // close setup pipe as setup is now complete
if err := setup.Close(); err != nil { if err := closeSetup(); err != nil {
fmsg.Println("cannot close setup pipe:", err) fmsg.Println("cannot close setup pipe:", err)
// not fatal // not fatal
} }

32
internal/proc/fd.go Normal file
View File

@ -0,0 +1,32 @@
package proc
import (
"encoding/gob"
"errors"
"os"
"strconv"
)
var (
ErrNotSet = errors.New("environment variable not set")
ErrInvalid = errors.New("bad file descriptor")
)
func Receive(key string, e any) (func() error, error) {
var setup *os.File
if s, ok := os.LookupEnv(key); !ok {
return nil, ErrNotSet
} else {
if fd, err := strconv.Atoi(s); err != nil {
return nil, err
} else {
setup = os.NewFile(uintptr(fd), "setup")
if setup == nil {
return nil, ErrInvalid
}
}
}
return func() error { return setup.Close() }, gob.NewDecoder(setup).Decode(e)
}