aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--flake.nix1
-rw-r--r--internal/sandbox/container_test.go16
-rw-r--r--ldd/exec.go52
-rw-r--r--ldd/ldd.go5
-rw-r--r--ldd/ldd_test.go11
-rw-r--r--package.nix1
6 files changed, 41 insertions, 45 deletions
diff --git a/flake.nix b/flake.nix
index 55aa2e1d..b1929d55 100644
--- a/flake.nix
+++ b/flake.nix
@@ -140,7 +140,6 @@
gcc
pkg-config
wayland-scanner
- bubblewrap
]
++ (
with pkgs.pkgsStatic;
diff --git a/internal/sandbox/container_test.go b/internal/sandbox/container_test.go
index 082d0dc3..6ef8cecd 100644
--- a/internal/sandbox/container_test.go
+++ b/internal/sandbox/container_test.go
@@ -69,10 +69,7 @@ func TestContainer(t *testing.T) {
container.Uid = 1000
container.Gid = 100
container.Hostname = tc.host
- container.CommandContext = func(ctx context.Context) *exec.Cmd {
- return exec.CommandContext(ctx, os.Args[0], "-test.v",
- "-test.run=TestHelperInit", "--", "init")
- }
+ container.CommandContext = commandContext
container.Flags |= tc.flags
container.Stdout, container.Stderr = os.Stdout, os.Stderr
container.Ops = tc.ops
@@ -89,7 +86,11 @@ func TestContainer(t *testing.T) {
Bind(os.Args[0], os.Args[0], 0)
// in case test has cgo enabled
var libPaths []string
- if entries, err := ldd.Exec(ctx, os.Args[0]); err != nil {
+ if entries, err := ldd.ExecFilter(ctx,
+ commandContext,
+ func(v []byte) []byte {
+ return bytes.SplitN(v, []byte("TestHelperInit\n"), 2)[1]
+ }, os.Args[0]); err != nil {
log.Fatalf("ldd: %v", err)
} else {
libPathsM := make(map[string]struct{}, len(entries))
@@ -175,3 +176,8 @@ func TestHelperCheckContainer(t *testing.T) {
t.Run("seccomp", func(t *testing.T) { check.MustAssertSeccomp() })
t.Run("mntent", func(t *testing.T) { check.MustAssertMounts("", "/proc/mounts", "/proc/self/fd/0") })
}
+
+func commandContext(ctx context.Context) *exec.Cmd {
+ return exec.CommandContext(ctx, os.Args[0], "-test.v",
+ "-test.run=TestHelperInit", "--", "init")
+}
diff --git a/ldd/exec.go b/ldd/exec.go
index 5c51c6a2..4f77ae30 100644
--- a/ldd/exec.go
+++ b/ldd/exec.go
@@ -7,8 +7,7 @@ import (
"os/exec"
"time"
- "git.gensokyo.uk/security/fortify/helper"
- "git.gensokyo.uk/security/fortify/helper/bwrap"
+ "git.gensokyo.uk/security/fortify/internal/sandbox"
)
const lddTimeout = 2 * time.Second
@@ -18,34 +17,31 @@ var (
msgStaticGlibc = []byte("not a dynamic executable")
)
-func Exec(ctx context.Context, p string) ([]*Entry, error) {
- var h helper.Helper
-
- if toolPath, err := exec.LookPath("ldd"); err != nil {
- return nil, err
- } else if h, err = helper.NewBwrap(
- (&bwrap.Config{
- Hostname: "fortify-ldd",
- Chdir: "/",
- Syscall: &bwrap.SyscallPolicy{DenyDevel: true, Multiarch: true},
- NewSession: true,
- DieWithParent: true,
- }).Bind("/", "/").DevTmpfs("/dev"), toolPath, false,
- nil, func(_, _ int) []string { return []string{p} },
- nil, nil,
- ); err != nil {
- return nil, err
- }
-
- stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
- h.Stdout(stdout).Stderr(stderr)
+func Exec(ctx context.Context, p string) ([]*Entry, error) { return ExecFilter(ctx, nil, nil, p) }
+func ExecFilter(ctx context.Context,
+ commandContext func(context.Context) *exec.Cmd,
+ f func([]byte) []byte,
+ p string) ([]*Entry, error) {
c, cancel := context.WithTimeout(ctx, lddTimeout)
defer cancel()
- if err := h.Start(c, false); err != nil {
+ container := sandbox.New(c, "ldd", p)
+ container.Hostname = "fortify-ldd"
+ stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
+ container.Stdout = stdout
+ container.Stderr = stderr
+ container.Bind("/", "/", 0).Dev("/dev")
+
+ if commandContext != nil {
+ container.CommandContext = commandContext
+ }
+
+ if err := container.Start(); err != nil {
+ return nil, err
+ } else if err = container.Serve(); err != nil {
return nil, err
}
- if err := h.Wait(); err != nil {
+ if err := container.Wait(); err != nil {
m := stderr.Bytes()
if bytes.Contains(m, append([]byte(p+": "), msgStatic...)) ||
bytes.Contains(m, msgStaticGlibc) {
@@ -56,5 +52,9 @@ func Exec(ctx context.Context, p string) ([]*Entry, error) {
return nil, err
}
- return Parse(stdout)
+ v := stdout.Bytes()
+ if f != nil {
+ v = f(v)
+ }
+ return Parse(v)
}
diff --git a/ldd/ldd.go b/ldd/ldd.go
index 434fbab6..ca4156c4 100644
--- a/ldd/ldd.go
+++ b/ldd/ldd.go
@@ -2,7 +2,6 @@
package ldd
import (
- "fmt"
"math"
"path"
"strconv"
@@ -15,8 +14,8 @@ type Entry struct {
Location uint64 `json:"location"`
}
-func Parse(stdout fmt.Stringer) ([]*Entry, error) {
- payload := strings.Split(strings.TrimSpace(stdout.String()), "\n")
+func Parse(p []byte) ([]*Entry, error) {
+ payload := strings.Split(strings.TrimSpace(string(p)), "\n")
result := make([]*Entry, len(payload))
for i, ent := range payload {
diff --git a/ldd/ldd_test.go b/ldd/ldd_test.go
index 2e5d010c..9c348c3c 100644
--- a/ldd/ldd_test.go
+++ b/ldd/ldd_test.go
@@ -3,7 +3,6 @@ package ldd_test
import (
"errors"
"reflect"
- "strings"
"testing"
"git.gensokyo.uk/security/fortify/ldd"
@@ -34,10 +33,7 @@ libzstd.so.1 => /usr/lib/libzstd.so.1 7ff71bfd2000
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- stdout := new(strings.Builder)
- stdout.WriteString(tc.out)
-
- if _, err := ldd.Parse(stdout); !errors.Is(err, tc.wantErr) {
+ if _, err := ldd.Parse([]byte(tc.out)); !errors.Is(err, tc.wantErr) {
t.Errorf("Parse() error = %v, wantErr %v", err, tc.wantErr)
}
})
@@ -111,10 +107,7 @@ libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7ff71c0a4000)`,
}
for _, tc := range testCases {
t.Run(tc.file, func(t *testing.T) {
- stdout := new(strings.Builder)
- stdout.WriteString(tc.out)
-
- if got, err := ldd.Parse(stdout); err != nil {
+ if got, err := ldd.Parse([]byte(tc.out)); err != nil {
t.Errorf("Parse() error = %v", err)
} else if !reflect.DeepEqual(got, tc.want) {
t.Errorf("Parse() got = %#v, want %#v", got, tc.want)
diff --git a/package.nix b/package.nix
index bdf95ca1..3088ec3e 100644
--- a/package.nix
+++ b/package.nix
@@ -73,7 +73,6 @@ buildGoModule rec {
pkg-config
wayland-scanner
makeBinaryWrapper
- bubblewrap
];
preBuild = ''