aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cmd/hakurei/command.go4
-rw-r--r--cmd/hakurei/parse_test.go2
-rw-r--r--cmd/hpkg/test/test.py4
-rw-r--r--cmd/hsu/hst.go16
-rw-r--r--cmd/hsu/main.go67
-rw-r--r--cmd/hsu/parse.go104
-rw-r--r--cmd/hsu/parse_test.go41
-rw-r--r--container/mount_test.go4
-rw-r--r--hst/config.go2
-rw-r--r--hst/container.go5
-rw-r--r--hst/grp_pwd.go61
-rw-r--r--hst/grp_pwd_test.go37
-rw-r--r--internal/outcome/hsu.go4
-rw-r--r--internal/outcome/main_test.go8
-rw-r--r--internal/outcome/outcome.go2
-rw-r--r--internal/outcome/shim_test.go2
-rw-r--r--internal/outcome/spx11_test.go6
-rw-r--r--internal/store/store.go2
-rw-r--r--internal/store/store_test.go2
-rw-r--r--nixos.nix7
-rw-r--r--test/sandbox/case/device.nix12
-rw-r--r--test/sandbox/case/mapuid.nix14
-rw-r--r--test/sandbox/case/pd.nix20
-rw-r--r--test/sandbox/case/pdlike.nix14
-rw-r--r--test/sandbox/case/preset.nix16
-rw-r--r--test/sandbox/case/tty.nix16
-rw-r--r--test/sandbox/test.py2
-rw-r--r--test/test.py16
28 files changed, 321 insertions, 169 deletions
diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go
index 6f727124..a741ecf6 100644
--- a/cmd/hakurei/command.go
+++ b/cmd/hakurei/command.go
@@ -86,7 +86,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
)
c.NewCommand("run", "Configure and start a permissive container", func(args []string) error {
- if flagIdentity < hst.IdentityMin || flagIdentity > hst.IdentityMax {
+ if flagIdentity < hst.IdentityStart || flagIdentity > hst.IdentityEnd {
log.Fatalf("identity %d out of range", flagIdentity)
}
@@ -95,7 +95,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr
passwd *user.User
passwdOnce sync.Once
passwdFunc = func() {
- us := strconv.Itoa(outcome.HsuUid(new(outcome.Hsu).MustID(msg), flagIdentity))
+ us := strconv.Itoa(hst.ToUser(new(outcome.Hsu).MustID(msg), flagIdentity))
if u, err := user.LookupId(us); err != nil {
msg.Verbosef("cannot look up uid %s", us)
passwd = &user.User{
diff --git a/cmd/hakurei/parse_test.go b/cmd/hakurei/parse_test.go
index e98e945f..ae7c8d51 100644
--- a/cmd/hakurei/parse_test.go
+++ b/cmd/hakurei/parse_test.go
@@ -41,7 +41,7 @@ func TestTryIdentifier(t *testing.T) {
{ID: (hst.ID)(bytes.Repeat([]byte{0xfe}, len(hst.ID{}))), PID: 0xbed, ShimPID: 0xfff, Config: func() *hst.Config {
template := hst.Template()
- template.Identity = hst.IdentityMax
+ template.Identity = hst.IdentityEnd
return template
}(), Time: time.Unix(0, 0xcafebabe0)},
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
diff --git a/cmd/hpkg/test/test.py b/cmd/hpkg/test/test.py
index 79d383ff..790377cc 100644
--- a/cmd/hpkg/test/test.py
+++ b/cmd/hpkg/test/test.py
@@ -92,11 +92,11 @@ machine.wait_for_file("/tmp/hakurei.0/tmpdir/2/success-client")
collect_state_ui("app_wayland")
check_state("foot", {"wayland": True, "dbus": True, "pulse": True})
# Verify acl on XDG_RUNTIME_DIR:
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000002"))
+print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10002"))
machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot")
# Verify acl cleanup on XDG_RUNTIME_DIR:
-machine.wait_until_fails("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000002")
+machine.wait_until_fails("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10002")
# Exit Sway and verify process exit status 0:
swaymsg("exit", succeed=False)
diff --git a/cmd/hsu/hst.go b/cmd/hsu/hst.go
new file mode 100644
index 00000000..d7ffb89a
--- /dev/null
+++ b/cmd/hsu/hst.go
@@ -0,0 +1,16 @@
+package main
+
+/* copied from hst and must never be changed */
+
+const (
+ userOffset = 100000
+ rangeSize = userOffset / 10
+
+ identityStart = 0
+ identityEnd = appEnd - appStart
+
+ appStart = rangeSize * 1
+ appEnd = appStart + rangeSize - 1
+)
+
+func toUser(userid, appid uint32) uint32 { return userid*userOffset + appStart + appid }
diff --git a/cmd/hsu/main.go b/cmd/hsu/main.go
index 7e3b3a7b..5c626a86 100644
--- a/cmd/hsu/main.go
+++ b/cmd/hsu/main.go
@@ -16,15 +16,12 @@ import (
)
const (
- hsuConfFile = "/etc/hsurc"
- envShim = "HAKUREI_SHIM"
- envIdentity = "HAKUREI_IDENTITY"
- envGroups = "HAKUREI_GROUPS"
-
- PR_SET_NO_NEW_PRIVS = 0x26
-
- identityMin = 0
- identityMax = 9999
+ // envIdentity is the name of the environment variable holding a
+ // single byte representing the shim setup pipe file descriptor.
+ envShim = "HAKUREI_SHIM"
+ // envGroups holds a ' ' separated list of string representations of
+ // supplementary group gid. Membership requirements are enforced.
+ envGroups = "HAKUREI_GROUPS"
)
// hakureiPath is the absolute path to Hakurei.
@@ -33,6 +30,7 @@ const (
var hakureiPath string
func main() {
+ const PR_SET_NO_NEW_PRIVS = 0x26
runtime.LockOSThread()
log.SetFlags(0)
@@ -68,13 +66,8 @@ func main() {
toolPath = p
}
- // uid = 1000000 +
- // id * 10000 +
- // identity
- uid := 1000000
-
// refuse to run if hsurc is not protected correctly
- if s, err := os.Stat(hsuConfFile); err != nil {
+ if s, err := os.Stat(hsuConfPath); err != nil {
log.Fatal(err)
} else if s.Mode().Perm() != 0400 {
log.Fatal("bad hsurc perm")
@@ -83,25 +76,13 @@ func main() {
}
// authenticate before accepting user input
- var id int
- if f, err := os.Open(hsuConfFile); err != nil {
- log.Fatal(err)
- } else if v, ok := mustParseConfig(f, puid); !ok {
- log.Fatalf("uid %d is not in the hsurc file", puid)
- } else {
- id = v
- if err = f.Close(); err != nil {
- log.Fatal(err)
- }
-
- uid += id * 10000
- }
+ userid := mustParseConfig(puid)
// pass through setup fd to shim
var shimSetupFd string
if s, ok := os.LookupEnv(envShim); !ok {
// hakurei requests hsurc user id
- fmt.Print(id)
+ fmt.Print(userid)
os.Exit(0)
} else if len(s) != 1 || s[0] > '9' || s[0] < '3' {
log.Fatal("HAKUREI_SHIM holds an invalid value")
@@ -109,13 +90,22 @@ func main() {
shimSetupFd = s
}
- // allowed identity range 0 to 9999
- if as, ok := os.LookupEnv(envIdentity); !ok {
- log.Fatal("HAKUREI_IDENTITY not set")
- } else if identity, err := parseUint32Fast(as); err != nil || identity < identityMin || identity > identityMax {
- log.Fatal("invalid identity")
- } else {
- uid += identity
+ // start is going ahead at this point
+ identity := mustReadIdentity()
+
+ const (
+ // first possible uid outcome
+ uidStart = 10000
+ // last possible uid outcome
+ uidEnd = 999919999
+ )
+
+ // cast to int for use with library functions
+ uid := int(toUser(userid, identity))
+
+ // final bounds check to catch any bugs
+ if uid < uidStart || uid >= uidEnd {
+ panic("uid out of bounds")
}
// supplementary groups
@@ -145,11 +135,6 @@ func main() {
suppGroups = []int{uid}
}
- // final bounds check to catch any bugs
- if uid < 1000000 || uid >= 2000000 {
- panic("uid out of bounds")
- }
-
// careful! users in the allowlist is effectively allowed to drop groups via hsu
if err := syscall.Setresgid(uid, uid, uid); err != nil {
diff --git a/cmd/hsu/parse.go b/cmd/hsu/parse.go
index 35704c61..6003f6cf 100644
--- a/cmd/hsu/parse.go
+++ b/cmd/hsu/parse.go
@@ -6,62 +6,128 @@ import (
"fmt"
"io"
"log"
+ "math"
+ "os"
"strings"
)
-func parseUint32Fast(s string) (int, error) {
+const (
+ // useridStart is the first userid.
+ useridStart = 0
+ // useridEnd is the last userid.
+ useridEnd = useridStart + rangeSize - 1
+)
+
+// parseUint32Fast parses a string representation of an unsigned 32-bit integer value
+// using the fast path only. This limits the range of values it is defined in.
+func parseUint32Fast(s string) (uint32, error) {
sLen := len(s)
if sLen < 1 {
- return -1, errors.New("zero length string")
+ return 0, errors.New("zero length string")
}
if sLen > 10 {
- return -1, errors.New("string too long")
+ return 0, errors.New("string too long")
}
- n := 0
+ var n uint32
for i, ch := range []byte(s) {
ch -= '0'
if ch > 9 {
- return -1, fmt.Errorf("invalid character '%s' at index %d", string(ch+'0'), i)
+ return 0, fmt.Errorf("invalid character '%s' at index %d", string(ch+'0'), i)
}
- n = n*10 + int(ch)
+ n = n*10 + uint32(ch)
}
return n, nil
}
-func parseConfig(r io.Reader, puid int) (fid int, ok bool, err error) {
+// parseConfig reads a list of allowed users from r until it encounters puid or [io.EOF].
+//
+// Each line of the file specifies a hakurei userid to kernel uid mapping. A line consists
+// of the string representation of the uid of the user wishing to start hakurei containers,
+// followed by a space, followed by the string representation of its userid. Duplicate uid
+// entries are ignored, with the first occurrence taking effect.
+//
+// All string representations are parsed by calling parseUint32Fast.
+func parseConfig(r io.Reader, puid uint32) (userid uint32, ok bool, err error) {
s := bufio.NewScanner(r)
- var line, puid0 int
+ var (
+ line uintptr
+ puid0 uint32
+ )
for s.Scan() {
line++
- // <puid> <fid>
+ // <puid> <userid>
lf := strings.SplitN(s.Text(), " ", 2)
if len(lf) != 2 {
- return -1, false, fmt.Errorf("invalid entry on line %d", line)
+ return useridEnd + 1, false, fmt.Errorf("invalid entry on line %d", line)
}
puid0, err = parseUint32Fast(lf[0])
if err != nil || puid0 < 1 {
- return -1, false, fmt.Errorf("invalid parent uid on line %d", line)
+ return useridEnd + 1, false, fmt.Errorf("invalid parent uid on line %d", line)
}
ok = puid0 == puid
if ok {
- // allowed fid range 0 to 99
- if fid, err = parseUint32Fast(lf[1]); err != nil || fid < 0 || fid > 99 {
- return -1, false, fmt.Errorf("invalid identity on line %d", line)
+ // userid bound to a range, uint32 size allows this to be increased if needed
+ if userid, err = parseUint32Fast(lf[1]); err != nil ||
+ userid < useridStart || userid > useridEnd {
+ return useridEnd + 1, false, fmt.Errorf("invalid userid on line %d", line)
}
return
}
}
- return -1, false, s.Err()
+ return useridEnd + 1, false, s.Err()
}
-func mustParseConfig(r io.Reader, puid int) (int, bool) {
- fid, ok, err := parseConfig(r, puid)
- if err != nil {
+// hsuConfPath is an absolute pathname to the hsu configuration file.
+// Its contents are interpreted by parseConfig.
+const hsuConfPath = "/etc/hsurc"
+
+// mustParseConfig calls parseConfig to interpret the contents of hsuConfPath,
+// terminating the program if an error is encountered, the syntax is incorrect,
+// or the current user is not authorised to use hsu because its uid is missing.
+//
+// Therefore, code after this function call can assume an authenticated state.
+//
+// mustParseConfig returns the userid value of the current user.
+func mustParseConfig(puid int) (userid uint32) {
+ if puid > math.MaxUint32 {
+ log.Fatalf("got impossible uid %d", puid)
+ }
+
+ var ok bool
+ if f, err := os.Open(hsuConfPath); err != nil {
+ log.Fatal(err)
+ } else if userid, ok, err = parseConfig(f, uint32(puid)); err != nil {
+ log.Fatal(err)
+ } else if err = f.Close(); err != nil {
log.Fatal(err)
}
- return fid, ok
+ if !ok {
+ log.Fatalf("uid %d is not in the hsurc file", puid)
+ }
+
+ return
+}
+
+// envIdentity is the name of the environment variable holding a
+// string representation of the current application identity.
+var envIdentity = "HAKUREI_IDENTITY"
+
+// mustReadIdentity calls parseUint32Fast to interpret the value stored in envIdentity,
+// terminating the program if the value is not set, malformed, or out of bounds.
+func mustReadIdentity() uint32 {
+ // ranges defined in hst and copied to this package to avoid importing hst
+ if as, ok := os.LookupEnv(envIdentity); !ok {
+ log.Fatal("HAKUREI_IDENTITY not set")
+ panic("unreachable")
+ } else if identity, err := parseUint32Fast(as); err != nil ||
+ identity < identityStart || identity > identityEnd {
+ log.Fatal("invalid identity")
+ panic("unreachable")
+ } else {
+ return identity
+ }
}
diff --git a/cmd/hsu/parse_test.go b/cmd/hsu/parse_test.go
index 7b5ec09f..d90851d7 100644
--- a/cmd/hsu/parse_test.go
+++ b/cmd/hsu/parse_test.go
@@ -2,6 +2,7 @@ package main
import (
"bytes"
+ "math"
"strconv"
"testing"
)
@@ -39,22 +40,20 @@ func TestParseUint32Fast(t *testing.T) {
t.Run("range", func(t *testing.T) {
t.Parallel()
- testRange := func(i, end int) {
+ testRange := func(i, end uint32) {
for ; i < end; i++ {
- s := strconv.Itoa(i)
+ s := strconv.Itoa(int(i))
w := i
t.Run("parse "+s, func(t *testing.T) {
t.Parallel()
v, err := parseUint32Fast(s)
if err != nil {
- t.Errorf("parseUint32Fast(%q): error = %v",
- s, err)
+ t.Errorf("parseUint32Fast(%q): error = %v", s, err)
return
}
if v != w {
- t.Errorf("parseUint32Fast(%q): got %v",
- s, v)
+ t.Errorf("parseUint32Fast(%q): got %v", s, v)
return
}
})
@@ -63,7 +62,7 @@ func TestParseUint32Fast(t *testing.T) {
testRange(0, 2500)
testRange(23002500, 23005000)
- testRange(7890002500, 7890005000)
+ testRange(math.MaxUint32-2500, math.MaxUint32)
})
}
@@ -72,14 +71,14 @@ func TestParseConfig(t *testing.T) {
testCases := []struct {
name string
- puid, want int
+ puid, want uint32
wantErr string
rc string
}{
- {"empty", 0, -1, "", ``},
- {"invalid field", 0, -1, "invalid entry on line 1", `9`},
- {"invalid puid", 0, -1, "invalid parent uid on line 1", `f 9`},
- {"invalid fid", 1000, -1, "invalid identity on line 1", `1000 f`},
+ {"empty", 0, useridEnd + 1, "", ``},
+ {"invalid field", 0, useridEnd + 1, "invalid entry on line 1", `9`},
+ {"invalid puid", 0, useridEnd + 1, "invalid parent uid on line 1", `f 9`},
+ {"invalid userid", 1000, useridEnd + 1, "invalid userid on line 1", `1000 f`},
{"match", 1000, 0, "", `1000 0`},
}
@@ -87,25 +86,21 @@ func TestParseConfig(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
- fid, ok, err := parseConfig(bytes.NewBufferString(tc.rc), tc.puid)
+ userid, ok, err := parseConfig(bytes.NewBufferString(tc.rc), tc.puid)
if err == nil && tc.wantErr != "" {
- t.Errorf("parseConfig: error = %v; wantErr %q",
- err, tc.wantErr)
+ t.Errorf("parseConfig: error = %v; want %q", err, tc.wantErr)
return
}
if err != nil && err.Error() != tc.wantErr {
- t.Errorf("parseConfig: error = %q; wantErr %q",
- err, tc.wantErr)
+ t.Errorf("parseConfig: error = %q; want %q", err, tc.wantErr)
return
}
- if ok == (tc.want == -1) {
- t.Errorf("parseConfig: ok = %v; want %v",
- ok, tc.want)
+ if ok == (tc.want == useridEnd+1) {
+ t.Errorf("parseConfig: ok = %v; want %v", ok, tc.want)
return
}
- if fid != tc.want {
- t.Errorf("parseConfig: fid = %v; want %v",
- fid, tc.want)
+ if userid != tc.want {
+ t.Errorf("parseConfig: %v; want %v", userid, tc.want)
}
})
}
diff --git a/container/mount_test.go b/container/mount_test.go
index c6a5710f..d08efa5e 100644
--- a/container/mount_test.go
+++ b/container/mount_test.go
@@ -69,8 +69,8 @@ func TestRemount(t *testing.T) {
403 397 0:63 / /host/run/user/1000 rw,nosuid,nodev,relatime master:295 - tmpfs tmpfs rw,size=401060k,nr_inodes=100265,mode=700,uid=1000,gid=100
404 254 0:46 / /host/mnt/cwd rw,relatime master:96 - overlay overlay rw,lowerdir=/mnt/.ro-cwd,upperdir=/tmp/.cwd/upper,workdir=/tmp/.cwd/work
405 254 0:47 / /host/mnt/src rw,relatime master:99 - overlay overlay rw,lowerdir=/nix/store/ihcrl3zwvp2002xyylri2wz0drwajx4z-ns0pa7q2b1jpx9pbf1l9352x6rniwxjn-source,upperdir=/tmp/.src/upper,workdir=/tmp/.src/work
-407 253 0:65 / / rw,nosuid,nodev,relatime - tmpfs rootfs rw,uid=1000000,gid=1000000
-408 407 0:65 /sysroot /sysroot rw,nosuid,nodev,relatime - tmpfs rootfs rw,uid=1000000,gid=1000000
+407 253 0:65 / / rw,nosuid,nodev,relatime - tmpfs rootfs rw,uid=10000,gid=10000
+408 407 0:65 /sysroot /sysroot rw,nosuid,nodev,relatime - tmpfs rootfs rw,uid=10000,gid=10000
409 408 253:0 /bin /sysroot/bin rw,nosuid,nodev,relatime master:1 - ext4 /dev/disk/by-label/nixos rw
410 408 253:0 /home /sysroot/home rw,nosuid,nodev,relatime master:1 - ext4 /dev/disk/by-label/nixos rw
411 408 253:0 /lib64 /sysroot/lib64 rw,nosuid,nodev,relatime master:1 - ext4 /dev/disk/by-label/nixos rw
diff --git a/hst/config.go b/hst/config.go
index ee31a555..d7078551 100644
--- a/hst/config.go
+++ b/hst/config.go
@@ -59,7 +59,7 @@ func (config *Config) Validate() error {
}
// this is checked again in hsu
- if config.Identity < IdentityMin || config.Identity > IdentityMax {
+ if config.Identity < IdentityStart || config.Identity > IdentityEnd {
return &AppError{Step: "validate configuration", Err: ErrIdentityBounds,
Msg: "identity " + strconv.Itoa(config.Identity) + " out of range"}
}
diff --git a/hst/container.go b/hst/container.go
index 75643913..f9cc95ed 100644
--- a/hst/container.go
+++ b/hst/container.go
@@ -20,11 +20,6 @@ const (
WaitDelayDefault = 5 * time.Second
// WaitDelayMax is used if WaitDelay exceeds its value.
WaitDelayMax = 30 * time.Second
-
- // IdentityMin is the minimum value of [Config.Identity]. This is enforced by cmd/hsu.
- IdentityMin = 0
- // IdentityMax is the maximum value of [Config.Identity]. This is enforced by cmd/hsu.
- IdentityMax = 9999
)
const (
diff --git a/hst/grp_pwd.go b/hst/grp_pwd.go
new file mode 100644
index 00000000..1a5c962e
--- /dev/null
+++ b/hst/grp_pwd.go
@@ -0,0 +1,61 @@
+package hst
+
+import (
+ "fmt"
+ "strconv"
+)
+
+const (
+ // UserOffset is the offset for UID and GID ranges for each user.
+ UserOffset = 100000
+ // RangeSize is the size of each UID and GID range.
+ RangeSize = UserOffset / 10
+
+ // IdentityStart is the first [Config.Identity] value. This is enforced in cmd/hsu.
+ IdentityStart = 0
+ // IdentityEnd is the last [Config.Identity] value. This is enforced in cmd/hsu.
+ IdentityEnd = AppEnd - AppStart
+
+ // AppStart is the first app user UID and GID.
+ AppStart = RangeSize * 1
+ // AppEnd is the last app user UID and GID.
+ AppEnd = AppStart + RangeSize - 1
+
+ /* these are for Rosa OS: use the ranges below to determine whether a process is isolated */
+
+ // IsolatedStart is the start of UID and GID for fully isolated sandboxed processes.
+ IsolatedStart = RangeSize * 9
+ // IsolatedEnd is the end of UID and GID for fully isolated sandboxed processes.
+ IsolatedEnd = IsolatedStart + RangeSize - 1
+)
+
+// A UID represents a kernel uid in the init namespace.
+type UID uint32
+
+// String returns the username corresponding to this uid.
+//
+// Not safe against untrusted input.
+func (uid UID) String() string {
+ appid := uid % UserOffset
+ userid := uid / UserOffset
+ if appid >= IsolatedStart && appid <= IsolatedEnd {
+ return fmt.Sprintf("u%d_i%d", userid, appid-IsolatedStart)
+ } else if appid >= AppStart && appid <= AppEnd {
+ return fmt.Sprintf("u%d_a%d", userid, appid-AppStart)
+ } else {
+ return strconv.Itoa(int(uid))
+ }
+}
+
+// A GID represents a kernel gid in the init namespace.
+type GID uint32
+
+// String returns the group name corresponding to this gid.
+//
+// Not safe against untrusted input.
+func (gid GID) String() string { return UID(gid).String() }
+
+// ToUser returns a [hst.UID] value from userid and appid.
+//
+// Not safe against untrusted input.
+func ToUser[U int | uint32](userid, appid U) U { return userid*UserOffset + AppStart + appid }
diff --git a/hst/grp_pwd_test.go b/hst/grp_pwd_test.go
new file mode 100644
index 00000000..2d01c122
--- /dev/null
+++ b/hst/grp_pwd_test.go
@@ -0,0 +1,37 @@
+package hst_test
+
+import (
+ "strconv"
+ "testing"
+
+ "hakurei.app/hst"
+)
+
+func TestUIDString(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ val uint32
+ want string
+ }{
+ {hst.AppStart + hst.IdentityStart, "u0_a0"}, // uidStart
+ {hst.ToUser[uint32](hst.RangeSize-1, hst.IdentityEnd), "u9999_a9999"}, // uidEnd
+
+ {hst.IsolatedStart + hst.IdentityStart, "u0_i0"}, // isolatedStart
+ {(hst.RangeSize-1)*hst.UserOffset + hst.IsolatedEnd, "u9999_i9999"}, // isolatedEnd
+
+ {0, "0"}, // out of bounds
+ }
+ for _, tc := range testCases {
+ t.Run(strconv.Itoa(int(tc.val)), func(t *testing.T) {
+ t.Parallel()
+
+ if got := hst.UID(tc.val).String(); got != tc.want {
+ t.Fatalf("UID.String: %q, want %q", got, tc.want)
+ }
+ if got := hst.GID(tc.val).String(); got != tc.want {
+ t.Fatalf("GID.String: %q, want %q", got, tc.want)
+ }
+ })
+ }
+}
diff --git a/internal/outcome/hsu.go b/internal/outcome/hsu.go
index b1107331..3047a2e9 100644
--- a/internal/outcome/hsu.go
+++ b/internal/outcome/hsu.go
@@ -95,7 +95,3 @@ func (h *Hsu) MustID(msg message.Msg) int {
return -0xdeadbeef // not reached
}
}
-
-// HsuUid returns target uid for the stable hsu uid format.
-// No bounds check is performed, a value retrieved by [Hsu] is expected.
-func HsuUid(id, identity int) int { return 1000000 + id*10000 + identity }
diff --git a/internal/outcome/main_test.go b/internal/outcome/main_test.go
index 14aa34d7..ea9c872c 100644
--- a/internal/outcome/main_test.go
+++ b/internal/outcome/main_test.go
@@ -40,7 +40,7 @@ func TestOutcomeMain(t *testing.T) {
wantSys *system.I
wantParams *container.Params
}{
- {"template", new(stubNixOS), hst.Template(), checkExpectInstanceId, system.New(panicMsgContext{}, message.New(nil), 1000009).
+ {"template", new(stubNixOS), hst.Template(), checkExpectInstanceId, system.New(panicMsgContext{}, message.New(nil), 10009).
// spParamsOp
Ensure(m("/tmp/hakurei.0"), 0711).
@@ -215,7 +215,7 @@ func TestOutcomeMain(t *testing.T) {
0x96, 0xd7, 0xbc, 0x15,
0xbd, 0x01, 0x78, 0x0e,
0xb9, 0xa6, 0x07, 0xac,
- }, system.New(t.Context(), msg, 1000000).
+ }, system.New(t.Context(), msg, 10000).
Ensure(m("/tmp/hakurei.0"), 0711).
Ensure(m("/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
@@ -339,7 +339,7 @@ func TestOutcomeMain(t *testing.T) {
0xb1, 0x75, 0x91, 0x17,
0x82, 0xd4, 0x13, 0x36,
0x9b, 0x64, 0xce, 0x7c,
- }, system.New(t.Context(), msg, 1000009).
+ }, system.New(t.Context(), msg, 10009).
Ensure(m("/tmp/hakurei.0"), 0711).
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/tmp/hakurei.0/runtime/9"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute).
@@ -493,7 +493,7 @@ func TestOutcomeMain(t *testing.T) {
0x66, 0xda, 0xbe, 0x57,
0x4c, 0xf0, 0x73, 0xbd,
0xb4, 0x6e, 0xb5, 0xc1,
- }, system.New(t.Context(), msg, 1000001).
+ }, system.New(t.Context(), msg, 10001).
Ensure(m("/tmp/hakurei.0"), 0711).
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/tmp/hakurei.0/runtime/1"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/1"), acl.Read, acl.Write, acl.Execute).
diff --git a/internal/outcome/outcome.go b/internal/outcome/outcome.go
index 9cf426f6..1af253ce 100644
--- a/internal/outcome/outcome.go
+++ b/internal/outcome/outcome.go
@@ -128,7 +128,7 @@ func (s *outcomeState) populateLocal(k syscallDispatcher, msg message.Msg) error
s.identity = newInt(s.Identity)
s.mapuid, s.mapgid = newInt(s.Mapuid), newInt(s.Mapgid)
- s.uid = newInt(HsuUid(s.UserID, s.identity.unwrap()))
+ s.uid = newInt(hst.ToUser(s.UserID, s.identity.unwrap()))
return nil
}
diff --git a/internal/outcome/shim_test.go b/internal/outcome/shim_test.go
index f16d3718..ad0fce6c 100644
--- a/internal/outcome/shim_test.go
+++ b/internal/outcome/shim_test.go
@@ -123,7 +123,7 @@ func TestShimEntrypoint(t *testing.T) {
templateState := outcomeState{
Shim: newShimParams(),
ID: &checkExpectInstanceId,
- Identity: hst.IdentityMax,
+ Identity: hst.IdentityEnd,
UserID: 10,
Container: hst.Template().Container,
Mapuid: 1000,
diff --git a/internal/outcome/spx11_test.go b/internal/outcome/spx11_test.go
index c958e946..85446a4d 100644
--- a/internal/outcome/spx11_test.go
+++ b/internal/outcome/spx11_test.go
@@ -60,7 +60,7 @@ func TestSpX11Op(t *testing.T) {
call("lookupEnv", stub.ExpectArgs{"DISPLAY"}, "unix:/tmp/.X11-unix/X0", nil),
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), os.ErrNotExist),
}, newI().
- ChangeHosts("#1000009"), nil, nil, insertsOps(nil), []stub.Call{
+ ChangeHosts("#10009"), nil, nil, insertsOps(nil), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Ops: new(container.Ops).
@@ -84,7 +84,7 @@ func TestSpX11Op(t *testing.T) {
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
}, newI().
UpdatePermType(hst.EX11, m("/tmp/.X11-unix/X0"), acl.Read, acl.Write, acl.Execute).
- ChangeHosts("#1000009"), nil, nil, insertsOps(nil), []stub.Call{
+ ChangeHosts("#10009"), nil, nil, insertsOps(nil), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Ops: new(container.Ops).
@@ -107,7 +107,7 @@ func TestSpX11Op(t *testing.T) {
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
}, newI().
UpdatePermType(hst.EX11, m("/tmp/.X11-unix/X0"), acl.Read, acl.Write, acl.Execute).
- ChangeHosts("#1000009"), nil, nil, insertsOps(nil), []stub.Call{
+ ChangeHosts("#10009"), nil, nil, insertsOps(nil), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Ops: new(container.Ops).
diff --git a/internal/store/store.go b/internal/store/store.go
index 7475c211..4fefd5c9 100644
--- a/internal/store/store.go
+++ b/internal/store/store.go
@@ -136,7 +136,7 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
si.Err = &hst.AppError{Step: step, Err: err,
Msg: "skipped non-identity entry " + strconv.Quote(ent.Name())}
goto out
- } else if v < hst.IdentityMin || v > hst.IdentityMax {
+ } else if v < hst.IdentityStart || v > hst.IdentityEnd {
si.Err = &hst.AppError{Step: step, Err: syscall.ERANGE,
Msg: "skipped out of bounds entry " + strconv.Itoa(v)}
goto out
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
index e37f1bf1..54f28bdd 100644
--- a/internal/store/store_test.go
+++ b/internal/store/store_test.go
@@ -339,7 +339,7 @@ func TestStoreAll(t *testing.T) {
{ID: (hst.ID)(bytes.Repeat([]byte{0xfe}, len(hst.ID{}))), PID: 0xbed, ShimPID: 0xfff, Config: func() *hst.Config {
template := hst.Template()
- template.Identity = hst.IdentityMax
+ template.Identity = hst.IdentityEnd
return template
}(), Time: time.Unix(0, 0xcafebabe0)},
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
diff --git a/nixos.nix b/nixos.nix
index b8759a9e..b23be279 100644
--- a/nixos.nix
+++ b/nixos.nix
@@ -20,9 +20,10 @@ let
cfg = config.environment.hakurei;
- getsubuid = fid: aid: 1000000 + fid * 10000 + aid;
- getsubname = fid: aid: "u${toString fid}_a${toString aid}";
- getsubhome = fid: aid: "${cfg.stateDir}/u${toString fid}/a${toString aid}";
+ # userid*userOffset + appStart + appid
+ getsubuid = userid: appid: userid * 100000 + 10000 + appid;
+ getsubname = userid: appid: "u${toString userid}_a${toString appid}";
+ getsubhome = userid: appid: "${cfg.stateDir}/u${toString userid}/a${toString appid}";
in
{
diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix
index dec3e380..b5678349 100644
--- a/test/sandbox/case/device.nix
+++ b/test/sandbox/case/device.nix
@@ -211,19 +211,19 @@ in
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10004,gid=10004")
(ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
(ent "/" ignore ignore ignore ignore ignore) # not deterministic
(ent "/" ignore ignore ignore ignore ignore)
(ent "/" ignore ignore ignore ignore ignore)
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000004,gid=1000004")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10004,gid=10004")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10004,gid=10004")
(ent "/tmp/hakurei.0/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (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 "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
(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)
diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix
index 1e007f1d..f5e33a5c 100644
--- a/test/sandbox/case/mapuid.nix
+++ b/test/sandbox/case/mapuid.nix
@@ -234,10 +234,10 @@ in
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000003,gid=1000003")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10003,gid=10003")
+ (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10003,gid=10003")
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
@@ -246,12 +246,12 @@ in
(ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000003,gid=1000003")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10003,gid=10003")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10003,gid=10003")
(ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
+ (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
(ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
(ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix
index 7ebd0b94..98627fe1 100644
--- a/test/sandbox/case/pd.nix
+++ b/test/sandbox/case/pd.nix
@@ -138,7 +138,7 @@
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
(ent "/bin" "/bin" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/home" "/home" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/lib64" "/lib64" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
@@ -169,8 +169,8 @@
(ent "/usr" "/usr" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000000,gid=1000000")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10000,gid=10000")
+ (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10000,gid=10000")
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
@@ -180,17 +180,17 @@
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
(ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000000,gid=1000000")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10000,gid=10000")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10000,gid=10000")
(ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
+ (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
(ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
- (ent "/" "/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
- (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
+ (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
+ (ent "/" "/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
+ (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
];
seccomp = true;
diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix
index e5354be3..d8de1abe 100644
--- a/test/sandbox/case/pdlike.nix
+++ b/test/sandbox/case/pdlike.nix
@@ -231,10 +231,10 @@ in
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000005,gid=1000005")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10005,gid=10005")
+ (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10005,gid=10005")
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
@@ -244,12 +244,12 @@ in
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
(ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000005,gid=1000005")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10005,gid=10005")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10005,gid=10005")
(ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
(ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
+ (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
(ent ignore "/run/user/65534/wayland-0" "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")
diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix
index 7cb6ed04..aabe2b06 100644
--- a/test/sandbox/case/preset.nix
+++ b/test/sandbox/case/preset.nix
@@ -230,10 +230,10 @@ in
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000001,gid=1000001")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10001,gid=10001")
+ (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10001,gid=10001")
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
@@ -242,11 +242,11 @@ in
(ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000001,gid=1000001")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000001,gid=1000001")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10001,gid=10001")
+ (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
+ (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
(ent ignore "/run/user/65534/wayland-0" "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")
diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix
index eca345af..8dbff164 100644
--- a/test/sandbox/case/tty.nix
+++ b/test/sandbox/case/tty.nix
@@ -238,10 +238,10 @@ in
} null;
mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
+ (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000002,gid=1000002")
+ (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10002,gid=10002")
+ (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10002,gid=10002")
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
@@ -251,12 +251,12 @@ in
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
(ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000002,gid=1000002")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
+ (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
+ (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10002,gid=10002")
(ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000002,gid=1000002")
- (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 "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
+ (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
+ (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
(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)
diff --git a/test/sandbox/test.py b/test/sandbox/test.py
index b36e9ab7..bce493b4 100644
--- a/test/sandbox/test.py
+++ b/test/sandbox/test.py
@@ -26,7 +26,7 @@ def swaymsg(command: str = "", succeed=True, type="command"):
def check_filter(check_offset, name, pname):
- pid = int(machine.wait_until_succeeds(f"pgrep -U {1000000+check_offset} -x {pname}", timeout=60))
+ pid = int(machine.wait_until_succeeds(f"pgrep -U {10000+check_offset} -x {pname}", timeout=60))
hash = machine.succeed(f"sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-1 check-sandbox-{name} hash")
print(machine.succeed(f"hakurei-test -s {hash} filter {pid}"))
diff --git a/test/test.py b/test/test.py
index 80cfa1be..1d172d96 100644
--- a/test/test.py
+++ b/test/test.py
@@ -160,17 +160,17 @@ machine.succeed("pkill -9 mako")
# Check revert type selection:
hakurei("-v run --wayland -X --dbus --pulse -u p0 foot && touch /tmp/p0-exit-ok")
wait_for_window("p0@machine")
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000"))
+print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10000"))
hakurei("-v run --wayland -X --dbus --pulse -u p1 foot && touch /tmp/p1-exit-ok")
wait_for_window("p1@machine")
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000"))
+print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10000"))
machine.send_chars("exit\n")
machine.wait_for_file("/tmp/p1-exit-ok", timeout=15)
# Verify acl is kept alive:
-print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000"))
+print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10000"))
machine.send_chars("exit\n")
machine.wait_for_file("/tmp/p0-exit-ok", timeout=15)
-machine.fail("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 1000000")
+machine.fail("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10000")
# Check interrupt shim behaviour:
swaymsg("exec sh -c 'ne-foot; echo -n $? > /tmp/monitor-exit-code'")
@@ -209,10 +209,10 @@ machine.wait_for_file("/var/tmp/client-ok", timeout=15)
collect_state_ui("foot_wayland")
check_state("ne-foot", {"wayland": True})
# Verify lack of acl on XDG_RUNTIME_DIR:
-machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 1000000}")
+machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}")
machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot", timeout=5)
-machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 1000000}", timeout=5)
+machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}", timeout=5)
# Test PulseAudio (hakurei does not support PipeWire yet):
swaymsg("exec pa-foot")
@@ -242,11 +242,11 @@ collect_state_ui("foot_direct")
machine.wait_for_file("/var/tmp/direct-ok", timeout=15)
check_state("da-foot", {"wayland": True})
# Verify acl on XDG_RUNTIME_DIR:
-print(machine.succeed(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 1000000}"))
+print(machine.succeed(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 10000}"))
machine.send_chars("exit\n")
machine.wait_until_fails("pgrep foot", timeout=5)
# Verify acl cleanup on XDG_RUNTIME_DIR:
-machine.wait_until_fails(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 1000000}", timeout=5)
+machine.wait_until_fails(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 10000}", timeout=5)
# Test syscall filter:
print(machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 strace-failure"))