diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go index 6f72712..a741ecf 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 e98e945..ae7c8d5 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/hsu/hst.go b/cmd/hsu/hst.go new file mode 100644 index 0000000..d7ffb89 --- /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 7e3b3a7..5c626a8 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 35704c6..6003f6c 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++ - // + // 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 7b5ec09..d90851d 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 c6a5710..d08efa5 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 ee31a55..d707855 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 7564391..f9cc95e 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 0000000..1a5c962 --- /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 0000000..2d01c12 --- /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 b110733..3047a2e 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 14aa34d..ea9c872 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 9cf426f..1af253c 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 f16d371..ad0fce6 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 c958e94..85446a4 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 7475c21..4fefd5c 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 e37f1bf..54f28bd 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 b8759a9..b23be27 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 dec3e38..b567834 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 1e007f1..f5e33a5 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 7ebd0b9..98627fe 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 e5354be..d8de1ab 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 7cb6ed0..aabe2b0 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 eca345a..8dbff16 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 b36e9ab..bce493b 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 80cfa1b..1d172d9 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"))