Compare commits

...

2 Commits

Author SHA1 Message Date
715addaccd
helper/bwrap: append --sync-fd before --
All checks were successful
Build / Create distribution (push) Successful in 1m26s
Test / Run NixOS test (push) Successful in 3m26s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-01-18 12:30:03 +09:00
b31d055e20
proc/priv/init: early init check
All checks were successful
Build / Create distribution (push) Successful in 1m39s
Test / Run NixOS test (push) Successful in 3m45s
Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-01-18 12:33:33 +09:00
5 changed files with 35 additions and 19 deletions

View File

@ -49,6 +49,11 @@ func (b *bubblewrap) StartNotify(ready chan error) error {
return errors.New("exec: already started")
}
// pass sync fd to bwrap
if b.sync != nil {
b.Cmd.Args = append(b.Cmd.Args, "--sync-fd", strconv.Itoa(int(proc.ExtraFile(b.Cmd, b.sync))))
}
// prepare bwrap pipe and args
if argsFD, _, err := b.control.prepareCmd(b.Cmd); err != nil {
return err
@ -76,10 +81,6 @@ func (b *bubblewrap) StartNotify(ready chan error) error {
b.Cmd.Env = append(b.Cmd.Env, FortifyHelper+"=1", FortifyStatus+"=-1")
}
if b.sync != nil {
b.Cmd.Args = append(b.Cmd.Args, "--sync-fd", strconv.Itoa(int(proc.ExtraFile(b.Cmd, b.sync))))
}
if err := b.Cmd.Start(); err != nil {
return err
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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()

View File

@ -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