aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--internal/app/seal_linux.go28
-rw-r--r--test/sandbox/assert.go46
-rw-r--r--test/sandbox/case/default.nix3
-rw-r--r--test/sandbox/case/device.nix11
-rw-r--r--test/sandbox/case/mapuid.nix5
-rw-r--r--test/sandbox/case/pdlike.nix5
-rw-r--r--test/sandbox/case/preset.nix5
-rw-r--r--test/sandbox/case/tty.nix11
8 files changed, 111 insertions, 3 deletions
diff --git a/internal/app/seal_linux.go b/internal/app/seal_linux.go
index 49ef78f7..c7293720 100644
--- a/internal/app/seal_linux.go
+++ b/internal/app/seal_linux.go
@@ -12,6 +12,7 @@ import (
"path"
"regexp"
"slices"
+ "strconv"
"strings"
"sync/atomic"
"syscall"
@@ -386,9 +387,34 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
return hlog.WrapErr(ErrXDisplay,
"DISPLAY is not set")
} else {
+ socketDir := container.AbsFHSTmp.Append(".X11-unix")
+
+ // the socket file at `/tmp/.X11-unix/X%d` is typically owned by the priv user
+ // and not accessible by the target user
+ var socketPath *container.Absolute
+ if len(d) > 1 && d[0] == ':' { // `:%d`
+ if n, err := strconv.Atoi(d[1:]); err == nil && n >= 0 {
+ socketPath = socketDir.Append("X" + strconv.Itoa(n))
+ }
+ } else if len(d) > 5 && strings.HasPrefix(d, "unix:") { // `unix:%s`
+ if a, err := container.NewAbs(d[5:]); err == nil {
+ socketPath = a
+ }
+ }
+ if socketPath != nil {
+ if _, err := sys.Stat(socketPath.String()); err != nil {
+ if !errors.Is(err, fs.ErrNotExist) {
+ return hlog.WrapErrSuffix(err,
+ fmt.Sprintf("cannot access X11 socket %q:", socketPath))
+ }
+ } else {
+ seal.sys.UpdatePermType(system.EX11, socketPath.String(), acl.Read, acl.Write, acl.Execute)
+ d = "unix:" + socketPath.String()
+ }
+ }
+
seal.sys.ChangeHosts("#" + seal.user.uid.String())
seal.env[display] = d
- socketDir := container.AbsFHSTmp.Append(".X11-unix")
seal.container.Bind(socketDir, socketDir, 0)
}
}
diff --git a/test/sandbox/assert.go b/test/sandbox/assert.go
index 57d17039..2c2c9f20 100644
--- a/test/sandbox/assert.go
+++ b/test/sandbox/assert.go
@@ -15,6 +15,7 @@ import (
"errors"
"io/fs"
"log"
+ "net"
"os"
"syscall"
)
@@ -33,6 +34,10 @@ type TestCase struct {
FS *FS `json:"fs"`
Mount []*MountinfoEntry `json:"mount"`
Seccomp bool `json:"seccomp"`
+
+ TrySocket string `json:"try_socket,omitempty"`
+ SocketAbstract bool `json:"socket_abstract,omitempty"`
+ SocketPathname bool `json:"socket_pathname,omitempty"`
}
type T struct {
@@ -125,6 +130,47 @@ func (t *T) MustCheck(want *TestCase) {
} else {
printf("[SKIP] skipping seccomp check")
}
+
+ if want.TrySocket != "" {
+ abstractConn, abstractErr := net.Dial("unix", "@"+want.TrySocket)
+ pathnameConn, pathnameErr := net.Dial("unix", want.TrySocket)
+ ok := true
+
+ if abstractErr == nil {
+ if err := abstractConn.Close(); err != nil {
+ ok = false
+ log.Printf("Close: %v", err)
+ }
+ }
+ if pathnameErr == nil {
+ if err := pathnameConn.Close(); err != nil {
+ ok = false
+ log.Printf("Close: %v", err)
+ }
+ }
+
+ abstractWantErr := error(syscall.EPERM)
+ pathnameWantErr := error(syscall.ENOENT)
+ if want.SocketAbstract {
+ abstractWantErr = nil
+ }
+ if want.SocketPathname {
+ pathnameWantErr = nil
+ }
+
+ if !errors.Is(abstractErr, abstractWantErr) {
+ ok = false
+ log.Printf("abstractErr: %v, want %v", abstractErr, abstractWantErr)
+ }
+ if !errors.Is(pathnameErr, pathnameWantErr) {
+ ok = false
+ log.Printf("pathnameErr: %v, want %v", pathnameErr, pathnameWantErr)
+ }
+
+ if !ok {
+ os.Exit(1)
+ }
+ }
}
func MustCheckFilter(pid int, want string) {
diff --git a/test/sandbox/case/default.nix b/test/sandbox/case/default.nix
index 6db1ff45..ec814aab 100644
--- a/test/sandbox/case/default.nix
+++ b/test/sandbox/case/default.nix
@@ -50,6 +50,9 @@ let
useCommonPaths
userns
;
+ enablements = {
+ inherit (tc) x11;
+ };
share = testProgram;
packages = [ ];
path = "${testProgram}/bin/hakurei-test";
diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix
index fb2a54f2..e9cf724b 100644
--- a/test/sandbox/case/device.nix
+++ b/test/sandbox/case/device.nix
@@ -25,6 +25,7 @@ in
mapRealUid = false;
useCommonPaths = true;
userns = false;
+ x11 = true;
# 0, PresetStrict
expectedFilter = {
@@ -35,6 +36,7 @@ in
want = {
env = [
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
+ "DISPLAY=unix:/tmp/.X11-unix/X0"
"HOME=/var/lib/hakurei/u0/a4"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
"SHELL=/run/current-system/sw/bin/bash"
@@ -161,7 +163,9 @@ in
} null;
devices = fs "800001ed" null null;
} null;
- tmp = fs "800001f8" { } null;
+ tmp = fs "800001f8" {
+ ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
+ } null;
usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
var = fs "800001c0" {
lib = fs "800001c0" {
@@ -231,10 +235,15 @@ in
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
];
seccomp = true;
+
+ try_socket = "/tmp/.X11-unix/X0";
+ socket_abstract = true;
+ socket_pathname = true;
};
}
diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix
index 1069f9fa..18d82e77 100644
--- a/test/sandbox/case/mapuid.nix
+++ b/test/sandbox/case/mapuid.nix
@@ -34,6 +34,7 @@ in
mapRealUid = true;
useCommonPaths = true;
userns = false;
+ x11 = false;
# 0, PresetStrict
expectedFilter = {
@@ -266,5 +267,9 @@ in
];
seccomp = true;
+
+ try_socket = "/tmp/.X11-unix/X0";
+ socket_abstract = true;
+ socket_pathname = false;
};
}
diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix
index 4f0e71c4..da6753f8 100644
--- a/test/sandbox/case/pdlike.nix
+++ b/test/sandbox/case/pdlike.nix
@@ -34,6 +34,7 @@ in
mapRealUid = false;
useCommonPaths = false;
userns = true;
+ x11 = false;
# 0, PresetExt | PresetDenyDevel
expectedFilter = {
@@ -261,5 +262,9 @@ in
];
seccomp = true;
+
+ try_socket = "/tmp/.X11-unix/X0";
+ socket_abstract = true;
+ socket_pathname = false;
};
}
diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix
index 60257ad0..be376a17 100644
--- a/test/sandbox/case/preset.nix
+++ b/test/sandbox/case/preset.nix
@@ -34,6 +34,7 @@ in
mapRealUid = false;
useCommonPaths = false;
userns = false;
+ x11 = false;
# 0, PresetStrict
expectedFilter = {
@@ -259,5 +260,9 @@ in
];
seccomp = true;
+
+ try_socket = "/tmp/.X11-unix/X0";
+ socket_abstract = true;
+ socket_pathname = false;
};
}
diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix
index 267ac661..ff7bf035 100644
--- a/test/sandbox/case/tty.nix
+++ b/test/sandbox/case/tty.nix
@@ -34,6 +34,7 @@ in
mapRealUid = false;
useCommonPaths = true;
userns = false;
+ x11 = true;
# 0, PresetExt | PresetDenyNS | PresetDenyDevel
expectedFilter = {
@@ -44,6 +45,7 @@ in
want = {
env = [
"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
+ "DISPLAY=unix:/tmp/.X11-unix/X0"
"HOME=/var/lib/hakurei/u0/a2"
"PULSE_SERVER=unix:/run/user/65534/pulse/native"
"SHELL=/run/current-system/sw/bin/bash"
@@ -188,7 +190,9 @@ in
} null;
devices = fs "800001ed" null null;
} null;
- tmp = fs "800001f8" { } null;
+ tmp = fs "800001f8" {
+ ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
+ } null;
usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
var = fs "800001c0" {
lib = fs "800001c0" {
@@ -263,10 +267,15 @@ in
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
+ (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
];
seccomp = true;
+
+ try_socket = "/tmp/.X11-unix/X0";
+ socket_abstract = true;
+ socket_pathname = true;
};
}