app: integrate security-context-v1
All checks were successful
test / test (push) Successful in 37s

Should be able to get rid of XDG_RUNTIME_DIR share after this.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
2024-12-06 04:25:33 +09:00
parent 8d0573405a
commit b3ef53b193
12 changed files with 57 additions and 185 deletions

View File

@@ -7,8 +7,6 @@ type Payload struct {
Argv0 string
// child full argv
Argv []string
// wayland fd, -1 to disable
WL int
// verbosity pass through
Verbose bool

View File

@@ -92,14 +92,6 @@ func main() {
cmd.Args = payload.Argv
cmd.Env = os.Environ()
// pass wayland fd
if payload.WL != -1 {
if f := os.NewFile(uintptr(payload.WL), "wayland"); f != nil {
cmd.Env = append(cmd.Env, "WAYLAND_SOCKET="+strconv.Itoa(3+len(cmd.ExtraFiles)))
cmd.ExtraFiles = append(cmd.ExtraFiles, f)
}
}
if err := cmd.Start(); err != nil {
fmsg.Fatalf("cannot start %q: %v", payload.Argv0, err)
}

View File

@@ -2,7 +2,6 @@ package shim0
import (
"encoding/gob"
"errors"
"net"
"git.ophivana.moe/security/fortify/helper/bwrap"
@@ -18,25 +17,19 @@ type Payload struct {
Exec [2]string
// bwrap config
Bwrap *bwrap.Config
// whether to pass wayland fd
WL bool
// sync fd
Sync *uintptr
// verbosity pass through
Verbose bool
}
func (p *Payload) Serve(conn *net.UnixConn, wl *Wayland) error {
func (p *Payload) Serve(conn *net.UnixConn) error {
if err := gob.NewEncoder(conn).Encode(*p); err != nil {
return fmsg.WrapErrorSuffix(err,
"cannot stream shim payload:")
}
if wl != nil {
if err := wl.WriteUnix(conn); err != nil {
return errors.Join(err, conn.Close())
}
}
return fmsg.WrapErrorSuffix(conn.Close(),
"cannot close setup connection:")
}

View File

@@ -39,14 +39,12 @@ type Shim struct {
abortOnce sync.Once
// fallback exit notifier with error returned killing the process
killFallback chan error
// wayland mediation, nil if disabled
wl *shim0.Wayland
// shim setup payload
payload *shim0.Payload
}
func New(uid uint32, aid string, supp []string, socket string, wl *shim0.Wayland, payload *shim0.Payload) *Shim {
return &Shim{uid: uid, aid: aid, supp: supp, socket: socket, wl: wl, payload: payload}
func New(uid uint32, aid string, supp []string, socket string, payload *shim0.Payload) *Shim {
return &Shim{uid: uid, aid: aid, supp: supp, socket: socket, payload: payload}
}
func (s *Shim) String() string {
@@ -112,6 +110,14 @@ func (s *Shim) Start() (*time.Time, error) {
}
s.cmd.Stdin, s.cmd.Stdout, s.cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
s.cmd.Dir = "/"
// pass sync fd if set
if s.payload.Bwrap.Sync() != nil {
fd := uintptr(3 + len(s.cmd.ExtraFiles))
s.payload.Sync = &fd
s.cmd.ExtraFiles = append(s.cmd.ExtraFiles, s.payload.Bwrap.Sync())
}
fmsg.VPrintln("starting shim via fsu:", s.cmd)
fmsg.Suspend() // withhold messages to stderr
if err := s.cmd.Start(); err != nil {
@@ -172,9 +178,9 @@ func (s *Shim) Start() (*time.Time, error) {
return &startTime, err
}
// serve payload and wayland fd if enabled
// serve payload
// this also closes the connection
err := s.payload.Serve(conn, s.wl)
err := s.payload.Serve(conn)
if err == nil {
killShim = func() {}
}

View File

@@ -1,75 +0,0 @@
package shim0
import (
"fmt"
"net"
"sync"
"syscall"
"git.ophivana.moe/security/fortify/internal/fmsg"
)
// Wayland implements wayland mediation.
type Wayland struct {
// wayland socket path
Path string
// wayland connection
conn *net.UnixConn
connErr error
sync.Once
// wait for wayland client to exit
done chan struct{}
}
func (wl *Wayland) WriteUnix(conn *net.UnixConn) error {
// connect to host wayland socket
if f, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: wl.Path, Net: "unix"}); err != nil {
return fmsg.WrapErrorSuffix(err,
fmt.Sprintf("cannot connect to wayland at %q:", wl.Path))
} else {
fmsg.VPrintf("connected to wayland at %q", wl.Path)
wl.conn = f
}
// set up for passing wayland socket
if rc, err := wl.conn.SyscallConn(); err != nil {
return fmsg.WrapErrorSuffix(err, "cannot obtain raw wayland connection:")
} else {
ec := make(chan error)
go func() {
// pass wayland connection fd
if err = rc.Control(func(fd uintptr) {
if _, _, err = conn.WriteMsgUnix(nil, syscall.UnixRights(int(fd)), nil); err != nil {
ec <- fmsg.WrapErrorSuffix(err, "cannot pass wayland connection to shim:")
return
}
ec <- nil
// block until shim exits
<-wl.done
fmsg.VPrintln("releasing wayland connection")
}); err != nil {
ec <- fmsg.WrapErrorSuffix(err, "cannot obtain wayland connection fd:")
return
}
}()
return <-ec
}
}
func (wl *Wayland) Close() error {
wl.Do(func() {
close(wl.done)
wl.connErr = wl.conn.Close()
})
return wl.connErr
}
func NewWayland() *Wayland {
wl := new(Wayland)
wl.done = make(chan struct{})
return wl
}

View File

@@ -2,7 +2,6 @@ package main
import (
"encoding/gob"
"errors"
"net"
"os"
"path"
@@ -76,14 +75,9 @@ func main() {
fmsg.Fatal("bwrap config not supplied")
}
// receive wayland fd over socket
wfd := -1
if payload.WL {
if fd, err := receiveWLfd(conn); err != nil {
fmsg.Fatalf("cannot receive wayland fd: %v", err)
} else {
wfd = fd
}
// restore bwrap sync fd
if payload.Sync != nil {
payload.Bwrap.SetSync(os.NewFile(*payload.Sync, "sync"))
}
// close setup socket
@@ -116,16 +110,6 @@ func main() {
var extraFiles []*os.File
// pass wayland fd
if wfd != -1 {
if f := os.NewFile(uintptr(wfd), "wayland"); f != nil {
ic.WL = 3 + len(extraFiles)
extraFiles = append(extraFiles, f)
}
} else {
ic.WL = -1
}
// share config pipe
if r, w, err := os.Pipe(); err != nil {
fmsg.Fatalf("cannot pipe: %v", err)
@@ -168,30 +152,3 @@ func main() {
}
}
}
func receiveWLfd(conn *net.UnixConn) (int, error) {
oob := make([]byte, syscall.CmsgSpace(4)) // single fd
if _, oobn, _, _, err := conn.ReadMsgUnix(nil, oob); err != nil {
return -1, err
} else if len(oob) != oobn {
return -1, errors.New("invalid message length")
}
var msg syscall.SocketControlMessage
if messages, err := syscall.ParseSocketControlMessage(oob); err != nil {
return -1, err
} else if len(messages) != 1 {
return -1, errors.New("unexpected message count")
} else {
msg = messages[0]
}
if fds, err := syscall.ParseUnixRights(&msg); err != nil {
return -1, err
} else if len(fds) != 1 {
return -1, errors.New("unexpected fd count")
} else {
return fds[0], nil
}
}