aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-03-16 01:20:09 +0900
committerOphestra <cat@gensokyo.uk>2025-03-16 01:20:09 +0900
commit273d97af8502059193ccb6a188422f9d22eaf106 (patch)
treed26ae85bbdd32d15c8581627923c607a261370e3
parent891316d9240fc5cf451ad88f92e82f82b1751ab8 (diff)
ldd: lib paths resolve function
This is what always happens right after a ldd call, so implement it here. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--dbus/proc.go77
-rw-r--r--helper/stub.go16
-rw-r--r--internal/sandbox/container_test.go23
-rw-r--r--ldd/path.go21
4 files changed, 58 insertions, 79 deletions
diff --git a/dbus/proc.go b/dbus/proc.go
index 379f9fd3..15f02ac5 100644
--- a/dbus/proc.go
+++ b/dbus/proc.go
@@ -38,7 +38,6 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, sandbox bool) error
cmd.Env = make([]string, 0)
}, nil)
} else {
- // look up absolute path if name is just a file name
toolPath := p.name
if filepath.Base(p.name) == p.name {
if s, err := exec.LookPath(p.name); err != nil {
@@ -48,16 +47,6 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, sandbox bool) error
}
}
- // resolve libraries by parsing ldd output
- var proxyDeps []*ldd.Entry
- if toolPath != os.Args[0] {
- if l, err := ldd.Exec(ctx, toolPath); err != nil {
- return err
- } else {
- proxyDeps = l
- }
- }
-
bc := &bwrap.Config{
Hostname: "fortify-dbus",
Chdir: "/",
@@ -67,56 +56,48 @@ func (p *Proxy) Start(ctx context.Context, output io.Writer, sandbox bool) error
DieWithParent: true,
}
- // resolve proxy socket directories
- bindTargetM := make(map[string]struct{}, 2)
-
- for _, ps := range []string{p.session[1], p.system[1]} {
- if pd := path.Dir(ps); len(pd) > 0 {
- if pd[0] == '/' {
- bindTargetM[pd] = struct{}{}
+ // these lib paths are unpredictable, so mount them first so they cannot cover anything
+ if toolPath != os.Args[0] {
+ if entries, err := ldd.Exec(ctx, toolPath); err != nil {
+ return err
+ } else {
+ for _, name := range ldd.Path(entries) {
+ bc.Bind(name, name)
}
}
}
- bindTarget := make([]string, 0, len(bindTargetM))
- for k := range bindTargetM {
- bindTarget = append(bindTarget, k)
- }
- slices.Sort(bindTarget)
- for _, name := range bindTarget {
- bc.Bind(name, name, false, true)
- }
-
- roBindTargetM := make(map[string]struct{}, 2+1+len(proxyDeps))
-
- // xdb-dbus-proxy bin and dependencies
- roBindTargetM[path.Dir(toolPath)] = struct{}{}
- for _, ent := range proxyDeps {
- if path.IsAbs(ent.Path) {
- roBindTargetM[path.Dir(ent.Path)] = struct{}{}
- }
- if path.IsAbs(ent.Name) {
- roBindTargetM[path.Dir(ent.Name)] = struct{}{}
- }
- }
-
- // resolve upstream bus directories
+ // 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
- roBindTargetM[path.Dir(as[10:])] = struct{}{}
+ upstreamPaths = append(upstreamPaths, path.Dir(as[10:]))
}
}
+ slices.Sort(upstreamPaths)
+ upstreamPaths = slices.Compact(upstreamPaths)
+ for _, name := range upstreamPaths {
+ bc.Bind(name, name)
+ }
- roBindTarget := make([]string, 0, len(roBindTargetM))
- for k := range roBindTargetM {
- roBindTarget = append(roBindTarget, k)
+ // parent directories of bind paths
+ sockDirPaths := make([]string, 0, 2)
+ if d := path.Dir(p.session[1]); path.IsAbs(d) {
+ sockDirPaths = append(sockDirPaths, d)
}
- slices.Sort(roBindTarget)
- for _, name := range roBindTarget {
- bc.Bind(name, name)
+ if d := path.Dir(p.system[1]); path.IsAbs(d) {
+ sockDirPaths = append(sockDirPaths, d)
+ }
+ slices.Sort(sockDirPaths)
+ sockDirPaths = slices.Compact(sockDirPaths)
+ for _, name := range sockDirPaths {
+ bc.Bind(name, name, false, true)
}
+ // xdg-dbus-proxy bin path
+ binPath := path.Dir(toolPath)
+ bc.Bind(binPath, binPath)
h = helper.MustNewBwrap(c, toolPath,
p.seal, true,
argF, func(cmd *exec.Cmd) { cmdF(cmd, output, p.CmdF) },
diff --git a/helper/stub.go b/helper/stub.go
index 988004c2..942f1501 100644
--- a/helper/stub.go
+++ b/helper/stub.go
@@ -6,7 +6,6 @@ import (
"io"
"os"
"path"
- "slices"
"strconv"
"strings"
"syscall"
@@ -147,17 +146,10 @@ func bwrapStub() {
sc.Chdir = "/"
sc.Syscall = &bwrap.SyscallPolicy{DenyDevel: true, Multiarch: true}
sc.AsInit = false
-
- bindTarget := []string{"/tmp/fortify.1971/12622d846cc3fe7b4c10359d01f0eb47"}
- slices.Sort(bindTarget)
- for _, name := range bindTarget {
- sc.Bind(name, name, false, true)
- }
- roBindTarget := []string{"/run/user/1971", path.Dir(os.Args[0])}
- slices.Sort(roBindTarget)
- for _, name := range roBindTarget {
- sc.Bind(name, name)
- }
+ sc.
+ Bind("/run/user/1971", "/run/user/1971").
+ Bind("/tmp/fortify.1971/12622d846cc3fe7b4c10359d01f0eb47", "/tmp/fortify.1971/12622d846cc3fe7b4c10359d01f0eb47", false, true).
+ Bind(path.Dir(os.Args[0]), path.Dir(os.Args[0]))
// manipulate extra files list so fd ends up as 5
efp.Append()
diff --git a/internal/sandbox/container_test.go b/internal/sandbox/container_test.go
index 566de75c..1a629d99 100644
--- a/internal/sandbox/container_test.go
+++ b/internal/sandbox/container_test.go
@@ -7,8 +7,6 @@ import (
"log"
"os"
"os/exec"
- "path"
- "slices"
"syscall"
"testing"
"time"
@@ -94,23 +92,10 @@ func TestContainer(t *testing.T) {
}, os.Args[0]); err != nil {
log.Fatalf("ldd: %v", err)
} else {
- libPathsM := make(map[string]struct{}, len(entries))
- for _, ent := range entries {
- if path.IsAbs(ent.Path) {
- libPathsM[path.Dir(ent.Path)] = struct{}{}
- }
- if path.IsAbs(ent.Name) {
- libPathsM[path.Dir(ent.Name)] = struct{}{}
- }
- }
- libPaths = make([]string, 0, len(libPathsM))
- for name := range libPathsM {
- libPaths = append(libPaths, name)
- }
- slices.Sort(libPaths)
- for _, name := range libPaths {
- container.Bind(name, name, 0)
- }
+ libPaths = ldd.Path(entries)
+ }
+ for _, name := range libPaths {
+ container.Bind(name, name, 0)
}
mnt := make([]*check.Mntent, 0, 3+len(libPaths))
diff --git a/ldd/path.go b/ldd/path.go
new file mode 100644
index 00000000..4e41ce74
--- /dev/null
+++ b/ldd/path.go
@@ -0,0 +1,21 @@
+package ldd
+
+import (
+ "path"
+ "slices"
+)
+
+// Path returns a deterministic, deduplicated slice of absolute directory paths in entries.
+func Path(entries []*Entry) []string {
+ p := make([]string, 0, len(entries)*2)
+ for _, entry := range entries {
+ if path.IsAbs(entry.Path) {
+ p = append(p, path.Dir(entry.Path))
+ }
+ if path.IsAbs(entry.Name) {
+ p = append(p, path.Dir(entry.Name))
+ }
+ }
+ slices.Sort(p)
+ return slices.Compact(p)
+}