hst/grp_pwd: specify new uid format
All checks were successful
Test / Create distribution (push) Successful in 27s
Test / Sandbox (push) Successful in 41s
Test / Sandbox (race detector) (push) Successful in 41s
Test / Hpkg (push) Successful in 42s
Test / Hakurei (push) Successful in 47s
Test / Hakurei (race detector) (push) Successful in 46s
Test / Flake checks (push) Successful in 1m31s
All checks were successful
Test / Create distribution (push) Successful in 27s
Test / Sandbox (push) Successful in 41s
Test / Sandbox (race detector) (push) Successful in 41s
Test / Hpkg (push) Successful in 42s
Test / Hakurei (push) Successful in 47s
Test / Hakurei (race detector) (push) Successful in 46s
Test / Flake checks (push) Successful in 1m31s
This leaves slots available for additional uid ranges in Rosa OS. This breaks all existing installations! Users are required to fix ownership manually. Closes #18. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -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"}
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
61
hst/grp_pwd.go
Normal file
61
hst/grp_pwd.go
Normal file
@@ -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 }
|
||||
37
hst/grp_pwd_test.go
Normal file
37
hst/grp_pwd_test.go
Normal file
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user