aboutsummaryrefslogtreecommitdiffhomepage
path: root/dbus/proc.go
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/proc.go')
-rw-r--r--dbus/proc.go92
1 files changed, 51 insertions, 41 deletions
diff --git a/dbus/proc.go b/dbus/proc.go
index cd087d5f..d6fe0b01 100644
--- a/dbus/proc.go
+++ b/dbus/proc.go
@@ -3,14 +3,12 @@ package dbus
import (
"context"
"errors"
- "io"
"os"
"os/exec"
"path"
"path/filepath"
"slices"
"strconv"
- "strings"
"syscall"
"git.gensokyo.uk/security/fortify/helper"
@@ -19,25 +17,30 @@ import (
"git.gensokyo.uk/security/fortify/sandbox/seccomp"
)
-// Start launches the D-Bus proxy.
-func (p *Proxy) Start(ctx context.Context, output io.Writer, useSandbox bool) error {
- p.lock.Lock()
- defer p.lock.Unlock()
+// Start starts and configures a D-Bus proxy process.
+func (p *Proxy) Start() error {
+ if p.final == nil || p.final.WriterTo == nil {
+ return syscall.ENOTRECOVERABLE
+ }
+
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ p.pmu.Lock()
+ defer p.pmu.Unlock()
- if p.seal == nil {
- return errors.New("proxy not sealed")
+ if p.cancel != nil || p.cause != nil {
+ return errors.New("dbus: already started")
}
- var h helper.Helper
+ ctx, cancel := context.WithCancelCause(p.ctx)
- c, cancel := context.WithCancelCause(ctx)
- if !useSandbox {
- h = helper.NewDirect(c, p.name, p.seal, true, argF, func(cmd *exec.Cmd) {
+ if !p.useSandbox {
+ p.helper = helper.NewDirect(ctx, p.name, p.final, true, argF, func(cmd *exec.Cmd) {
if p.CmdF != nil {
p.CmdF(cmd)
}
- if output != nil {
- cmd.Stdout, cmd.Stderr = output, output
+ if p.output != nil {
+ cmd.Stdout, cmd.Stderr = p.output, p.output
}
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
cmd.Env = make([]string, 0)
@@ -59,15 +62,15 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, useSandbox bool) er
libPaths = ldd.Path(entries)
}
- h = helper.New(
- c, toolPath,
- p.seal, true,
+ p.helper = helper.New(
+ ctx, toolPath,
+ p.final, true,
argF, func(container *sandbox.Container) {
container.Seccomp |= seccomp.FilterMultiarch
container.Hostname = "fortify-dbus"
container.CommandContext = p.CommandContext
- if output != nil {
- container.Stdout, container.Stderr = output, output
+ if p.output != nil {
+ container.Stdout, container.Stderr = p.output, p.output
}
if p.CmdF != nil {
@@ -81,10 +84,17 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, useSandbox bool) er
// upstream bus directories
upstreamPaths := make([]string, 0, 2)
- for _, as := range []string{p.session[0], p.system[0]} {
- if len(as) > 0 && strings.HasPrefix(as, "unix:path=/") {
- // leave / intact
- upstreamPaths = append(upstreamPaths, path.Dir(as[10:]))
+ for _, addr := range [][]AddrEntry{p.final.SessionUpstream, p.final.SystemUpstream} {
+ for _, ent := range addr {
+ if ent.Method != "unix" {
+ continue
+ }
+ for _, pair := range ent.Values {
+ if pair[0] != "path" || !path.IsAbs(pair[1]) {
+ continue
+ }
+ upstreamPaths = append(upstreamPaths, path.Dir(pair[1]))
+ }
}
}
slices.Sort(upstreamPaths)
@@ -95,10 +105,10 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, useSandbox bool) er
// parent directories of bind paths
sockDirPaths := make([]string, 0, 2)
- if d := path.Dir(p.session[1]); path.IsAbs(d) {
+ if d := path.Dir(p.final.Session[1]); path.IsAbs(d) {
sockDirPaths = append(sockDirPaths, d)
}
- if d := path.Dir(p.system[1]); path.IsAbs(d) {
+ if d := path.Dir(p.final.System[1]); path.IsAbs(d) {
sockDirPaths = append(sockDirPaths, d)
}
slices.Sort(sockDirPaths)
@@ -113,14 +123,13 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, useSandbox bool) er
}, nil)
}
- if err := h.Start(); err != nil {
+ if err := p.helper.Start(); err != nil {
cancel(err)
+ p.helper = nil
return err
}
- p.helper = h
- p.ctx = c
- p.cancel = cancel
+ p.cancel, p.cause = cancel, func() error { return context.Cause(ctx) }
return nil
}
@@ -128,28 +137,30 @@ var proxyClosed = errors.New("proxy closed")
// Wait blocks until xdg-dbus-proxy exits and releases resources.
func (p *Proxy) Wait() error {
- p.lock.RLock()
- defer p.lock.RUnlock()
+ p.mu.RLock()
+ defer p.mu.RUnlock()
- if p.helper == nil {
+ p.pmu.RLock()
+ if p.helper == nil || p.cancel == nil || p.cause == nil {
+ p.pmu.RUnlock()
return errors.New("dbus: not started")
}
errs := make([]error, 3)
errs[0] = p.helper.Wait()
- if p.cancel == nil &&
- errors.Is(errs[0], context.Canceled) &&
- errors.Is(context.Cause(p.ctx), proxyClosed) {
+ if errors.Is(errs[0], context.Canceled) &&
+ errors.Is(p.cause(), proxyClosed) {
errs[0] = nil
}
+ p.pmu.RUnlock()
// ensure socket removal so ephemeral directory is empty at revert
- if err := os.Remove(p.session[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
+ if err := os.Remove(p.final.Session[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
errs[1] = err
}
- if p.sysP {
- if err := os.Remove(p.system[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
+ if p.final.System[1] != "" {
+ if err := os.Remove(p.final.System[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
errs[2] = err
}
}
@@ -159,14 +170,13 @@ func (p *Proxy) Wait() error {
// Close cancels the context passed to the helper instance attached to xdg-dbus-proxy.
func (p *Proxy) Close() {
- p.lock.Lock()
- defer p.lock.Unlock()
+ p.pmu.Lock()
+ defer p.pmu.Unlock()
if p.cancel == nil {
panic("dbus: not started")
}
p.cancel(proxyClosed)
- p.cancel = nil
}
func argF(argsFd, statFd int) []string {