hst/grp_pwd: specify new uid format
Some checks failed
Test / Create distribution (push) Successful in 26s
Test / Sandbox (push) Successful in 40s
Test / Hakurei (push) Successful in 45s
Test / Sandbox (race detector) (push) Successful in 1m0s
Test / Hpkg (push) Has been cancelled
Test / Hakurei (race detector) (push) Successful in 5m7s
Test / Flake checks (push) Has been skipped
Some checks failed
Test / Create distribution (push) Successful in 26s
Test / Sandbox (push) Successful in 40s
Test / Hakurei (push) Successful in 45s
Test / Sandbox (race detector) (push) Successful in 1m0s
Test / Hpkg (push) Has been cancelled
Test / Hakurei (race detector) (push) Successful in 5m7s
Test / Flake checks (push) Has been skipped
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:
parent
9a2a7b749f
commit
a1214d350c
@ -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 {
|
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)
|
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
|
passwd *user.User
|
||||||
passwdOnce sync.Once
|
passwdOnce sync.Once
|
||||||
passwdFunc = func() {
|
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 {
|
if u, err := user.LookupId(us); err != nil {
|
||||||
msg.Verbosef("cannot look up uid %s", us)
|
msg.Verbosef("cannot look up uid %s", us)
|
||||||
passwd = &user.User{
|
passwd = &user.User{
|
||||||
|
|||||||
@ -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 {
|
{ID: (hst.ID)(bytes.Repeat([]byte{0xfe}, len(hst.ID{}))), PID: 0xbed, ShimPID: 0xfff, Config: func() *hst.Config {
|
||||||
template := hst.Template()
|
template := hst.Template()
|
||||||
template.Identity = hst.IdentityMax
|
template.Identity = hst.IdentityEnd
|
||||||
return template
|
return template
|
||||||
}(), Time: time.Unix(0, 0xcafebabe0)},
|
}(), Time: time.Unix(0, 0xcafebabe0)},
|
||||||
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
|
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
|
||||||
|
|||||||
16
cmd/hsu/hst.go
Normal file
16
cmd/hsu/hst.go
Normal file
@ -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 }
|
||||||
@ -16,15 +16,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
hsuConfFile = "/etc/hsurc"
|
// envIdentity is the name of the environment variable holding a
|
||||||
envShim = "HAKUREI_SHIM"
|
// single byte representing the shim setup pipe file descriptor.
|
||||||
envIdentity = "HAKUREI_IDENTITY"
|
envShim = "HAKUREI_SHIM"
|
||||||
envGroups = "HAKUREI_GROUPS"
|
// envGroups holds a ' ' separated list of string representations of
|
||||||
|
// supplementary group gid. Membership requirements are enforced.
|
||||||
PR_SET_NO_NEW_PRIVS = 0x26
|
envGroups = "HAKUREI_GROUPS"
|
||||||
|
|
||||||
identityMin = 0
|
|
||||||
identityMax = 9999
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// hakureiPath is the absolute path to Hakurei.
|
// hakureiPath is the absolute path to Hakurei.
|
||||||
@ -33,6 +30,7 @@ const (
|
|||||||
var hakureiPath string
|
var hakureiPath string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
const PR_SET_NO_NEW_PRIVS = 0x26
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
@ -68,13 +66,8 @@ func main() {
|
|||||||
toolPath = p
|
toolPath = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// uid = 1000000 +
|
|
||||||
// id * 10000 +
|
|
||||||
// identity
|
|
||||||
uid := 1000000
|
|
||||||
|
|
||||||
// refuse to run if hsurc is not protected correctly
|
// 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)
|
log.Fatal(err)
|
||||||
} else if s.Mode().Perm() != 0400 {
|
} else if s.Mode().Perm() != 0400 {
|
||||||
log.Fatal("bad hsurc perm")
|
log.Fatal("bad hsurc perm")
|
||||||
@ -83,25 +76,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// authenticate before accepting user input
|
// authenticate before accepting user input
|
||||||
var id int
|
userid := mustParseConfig(puid)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// pass through setup fd to shim
|
// pass through setup fd to shim
|
||||||
var shimSetupFd string
|
var shimSetupFd string
|
||||||
if s, ok := os.LookupEnv(envShim); !ok {
|
if s, ok := os.LookupEnv(envShim); !ok {
|
||||||
// hakurei requests hsurc user id
|
// hakurei requests hsurc user id
|
||||||
fmt.Print(id)
|
fmt.Print(userid)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else if len(s) != 1 || s[0] > '9' || s[0] < '3' {
|
} else if len(s) != 1 || s[0] > '9' || s[0] < '3' {
|
||||||
log.Fatal("HAKUREI_SHIM holds an invalid value")
|
log.Fatal("HAKUREI_SHIM holds an invalid value")
|
||||||
@ -109,13 +90,22 @@ func main() {
|
|||||||
shimSetupFd = s
|
shimSetupFd = s
|
||||||
}
|
}
|
||||||
|
|
||||||
// allowed identity range 0 to 9999
|
// start is going ahead at this point
|
||||||
if as, ok := os.LookupEnv(envIdentity); !ok {
|
identity := mustReadIdentity()
|
||||||
log.Fatal("HAKUREI_IDENTITY not set")
|
|
||||||
} else if identity, err := parseUint32Fast(as); err != nil || identity < identityMin || identity > identityMax {
|
const (
|
||||||
log.Fatal("invalid identity")
|
// first possible uid outcome
|
||||||
} else {
|
uidStart = 10000
|
||||||
uid += identity
|
// 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
|
// supplementary groups
|
||||||
@ -145,11 +135,6 @@ func main() {
|
|||||||
suppGroups = []int{uid}
|
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
|
// careful! users in the allowlist is effectively allowed to drop groups via hsu
|
||||||
|
|
||||||
if err := syscall.Setresgid(uid, uid, uid); err != nil {
|
if err := syscall.Setresgid(uid, uid, uid); err != nil {
|
||||||
|
|||||||
104
cmd/hsu/parse.go
104
cmd/hsu/parse.go
@ -6,62 +6,128 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
"strings"
|
"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)
|
sLen := len(s)
|
||||||
if sLen < 1 {
|
if sLen < 1 {
|
||||||
return -1, errors.New("zero length string")
|
return 0, errors.New("zero length string")
|
||||||
}
|
}
|
||||||
if sLen > 10 {
|
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) {
|
for i, ch := range []byte(s) {
|
||||||
ch -= '0'
|
ch -= '0'
|
||||||
if ch > 9 {
|
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
|
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)
|
s := bufio.NewScanner(r)
|
||||||
var line, puid0 int
|
var (
|
||||||
|
line uintptr
|
||||||
|
puid0 uint32
|
||||||
|
)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
line++
|
line++
|
||||||
|
|
||||||
// <puid> <fid>
|
// <puid> <userid>
|
||||||
lf := strings.SplitN(s.Text(), " ", 2)
|
lf := strings.SplitN(s.Text(), " ", 2)
|
||||||
if len(lf) != 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])
|
puid0, err = parseUint32Fast(lf[0])
|
||||||
if err != nil || puid0 < 1 {
|
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
|
ok = puid0 == puid
|
||||||
if ok {
|
if ok {
|
||||||
// allowed fid range 0 to 99
|
// userid bound to a range, uint32 size allows this to be increased if needed
|
||||||
if fid, err = parseUint32Fast(lf[1]); err != nil || fid < 0 || fid > 99 {
|
if userid, err = parseUint32Fast(lf[1]); err != nil ||
|
||||||
return -1, false, fmt.Errorf("invalid identity on line %d", line)
|
userid < useridStart || userid > useridEnd {
|
||||||
|
return useridEnd + 1, false, fmt.Errorf("invalid userid on line %d", line)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1, false, s.Err()
|
return useridEnd + 1, false, s.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustParseConfig(r io.Reader, puid int) (int, bool) {
|
// hsuConfPath is an absolute pathname to the hsu configuration file.
|
||||||
fid, ok, err := parseConfig(r, puid)
|
// Its contents are interpreted by parseConfig.
|
||||||
if err != nil {
|
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)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -39,22 +40,20 @@ func TestParseUint32Fast(t *testing.T) {
|
|||||||
t.Run("range", func(t *testing.T) {
|
t.Run("range", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testRange := func(i, end int) {
|
testRange := func(i, end uint32) {
|
||||||
for ; i < end; i++ {
|
for ; i < end; i++ {
|
||||||
s := strconv.Itoa(i)
|
s := strconv.Itoa(int(i))
|
||||||
w := i
|
w := i
|
||||||
t.Run("parse "+s, func(t *testing.T) {
|
t.Run("parse "+s, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
v, err := parseUint32Fast(s)
|
v, err := parseUint32Fast(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("parseUint32Fast(%q): error = %v",
|
t.Errorf("parseUint32Fast(%q): error = %v", s, err)
|
||||||
s, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v != w {
|
if v != w {
|
||||||
t.Errorf("parseUint32Fast(%q): got %v",
|
t.Errorf("parseUint32Fast(%q): got %v", s, v)
|
||||||
s, v)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -63,7 +62,7 @@ func TestParseUint32Fast(t *testing.T) {
|
|||||||
|
|
||||||
testRange(0, 2500)
|
testRange(0, 2500)
|
||||||
testRange(23002500, 23005000)
|
testRange(23002500, 23005000)
|
||||||
testRange(7890002500, 7890005000)
|
testRange(math.MaxUint32-2500, math.MaxUint32)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,14 +71,14 @@ func TestParseConfig(t *testing.T) {
|
|||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
puid, want int
|
puid, want uint32
|
||||||
wantErr string
|
wantErr string
|
||||||
rc string
|
rc string
|
||||||
}{
|
}{
|
||||||
{"empty", 0, -1, "", ``},
|
{"empty", 0, useridEnd + 1, "", ``},
|
||||||
{"invalid field", 0, -1, "invalid entry on line 1", `9`},
|
{"invalid field", 0, useridEnd + 1, "invalid entry on line 1", `9`},
|
||||||
{"invalid puid", 0, -1, "invalid parent uid on line 1", `f 9`},
|
{"invalid puid", 0, useridEnd + 1, "invalid parent uid on line 1", `f 9`},
|
||||||
{"invalid fid", 1000, -1, "invalid identity on line 1", `1000 f`},
|
{"invalid userid", 1000, useridEnd + 1, "invalid userid on line 1", `1000 f`},
|
||||||
{"match", 1000, 0, "", `1000 0`},
|
{"match", 1000, 0, "", `1000 0`},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,25 +86,21 @@ func TestParseConfig(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Parallel()
|
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 != "" {
|
if err == nil && tc.wantErr != "" {
|
||||||
t.Errorf("parseConfig: error = %v; wantErr %q",
|
t.Errorf("parseConfig: error = %v; want %q", err, tc.wantErr)
|
||||||
err, tc.wantErr)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil && err.Error() != tc.wantErr {
|
if err != nil && err.Error() != tc.wantErr {
|
||||||
t.Errorf("parseConfig: error = %q; wantErr %q",
|
t.Errorf("parseConfig: error = %q; want %q", err, tc.wantErr)
|
||||||
err, tc.wantErr)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ok == (tc.want == -1) {
|
if ok == (tc.want == useridEnd+1) {
|
||||||
t.Errorf("parseConfig: ok = %v; want %v",
|
t.Errorf("parseConfig: ok = %v; want %v", ok, tc.want)
|
||||||
ok, tc.want)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if fid != tc.want {
|
if userid != tc.want {
|
||||||
t.Errorf("parseConfig: fid = %v; want %v",
|
t.Errorf("parseConfig: %v; want %v", userid, tc.want)
|
||||||
fid, tc.want)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
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
|
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
|
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
|
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=1000000,gid=1000000
|
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
|
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
|
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
|
411 408 253:0 /lib64 /sysroot/lib64 rw,nosuid,nodev,relatime master:1 - ext4 /dev/disk/by-label/nixos rw
|
||||||
|
|||||||
@ -59,7 +59,7 @@ func (config *Config) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is checked again in hsu
|
// 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,
|
return &AppError{Step: "validate configuration", Err: ErrIdentityBounds,
|
||||||
Msg: "identity " + strconv.Itoa(config.Identity) + " out of range"}
|
Msg: "identity " + strconv.Itoa(config.Identity) + " out of range"}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,11 +20,6 @@ const (
|
|||||||
WaitDelayDefault = 5 * time.Second
|
WaitDelayDefault = 5 * time.Second
|
||||||
// WaitDelayMax is used if WaitDelay exceeds its value.
|
// WaitDelayMax is used if WaitDelay exceeds its value.
|
||||||
WaitDelayMax = 30 * time.Second
|
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 (
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -95,7 +95,3 @@ func (h *Hsu) MustID(msg message.Msg) int {
|
|||||||
return -0xdeadbeef // not reached
|
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 }
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
wantSys *system.I
|
wantSys *system.I
|
||||||
wantParams *container.Params
|
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
|
// spParamsOp
|
||||||
Ensure(m("/tmp/hakurei.0"), 0711).
|
Ensure(m("/tmp/hakurei.0"), 0711).
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
0x96, 0xd7, 0xbc, 0x15,
|
0x96, 0xd7, 0xbc, 0x15,
|
||||||
0xbd, 0x01, 0x78, 0x0e,
|
0xbd, 0x01, 0x78, 0x0e,
|
||||||
0xb9, 0xa6, 0x07, 0xac,
|
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"), 0711).
|
||||||
Ensure(m("/tmp/hakurei.0/runtime"), 0700).
|
Ensure(m("/tmp/hakurei.0/runtime"), 0700).
|
||||||
UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
||||||
@ -339,7 +339,7 @@ func TestOutcomeMain(t *testing.T) {
|
|||||||
0xb1, 0x75, 0x91, 0x17,
|
0xb1, 0x75, 0x91, 0x17,
|
||||||
0x82, 0xd4, 0x13, 0x36,
|
0x82, 0xd4, 0x13, 0x36,
|
||||||
0x9b, 0x64, 0xce, 0x7c,
|
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"), 0711).
|
||||||
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
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).
|
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,
|
0x66, 0xda, 0xbe, 0x57,
|
||||||
0x4c, 0xf0, 0x73, 0xbd,
|
0x4c, 0xf0, 0x73, 0xbd,
|
||||||
0xb4, 0x6e, 0xb5, 0xc1,
|
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"), 0711).
|
||||||
Ensure(m("/tmp/hakurei.0/runtime"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
|
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).
|
Ensure(m("/tmp/hakurei.0/runtime/1"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/1"), acl.Read, acl.Write, acl.Execute).
|
||||||
|
|||||||
@ -128,7 +128,7 @@ func (s *outcomeState) populateLocal(k syscallDispatcher, msg message.Msg) error
|
|||||||
|
|
||||||
s.identity = newInt(s.Identity)
|
s.identity = newInt(s.Identity)
|
||||||
s.mapuid, s.mapgid = newInt(s.Mapuid), newInt(s.Mapgid)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,7 +123,7 @@ func TestShimEntrypoint(t *testing.T) {
|
|||||||
templateState := outcomeState{
|
templateState := outcomeState{
|
||||||
Shim: newShimParams(),
|
Shim: newShimParams(),
|
||||||
ID: &checkExpectInstanceId,
|
ID: &checkExpectInstanceId,
|
||||||
Identity: hst.IdentityMax,
|
Identity: hst.IdentityEnd,
|
||||||
UserID: 10,
|
UserID: 10,
|
||||||
Container: hst.Template().Container,
|
Container: hst.Template().Container,
|
||||||
Mapuid: 1000,
|
Mapuid: 1000,
|
||||||
|
|||||||
@ -60,7 +60,7 @@ func TestSpX11Op(t *testing.T) {
|
|||||||
call("lookupEnv", stub.ExpectArgs{"DISPLAY"}, "unix:/tmp/.X11-unix/X0", nil),
|
call("lookupEnv", stub.ExpectArgs{"DISPLAY"}, "unix:/tmp/.X11-unix/X0", nil),
|
||||||
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), os.ErrNotExist),
|
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), os.ErrNotExist),
|
||||||
}, newI().
|
}, 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
|
// this op configures the container state and does not make calls during toContainer
|
||||||
}, &container.Params{
|
}, &container.Params{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
@ -84,7 +84,7 @@ func TestSpX11Op(t *testing.T) {
|
|||||||
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
|
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
|
||||||
}, newI().
|
}, newI().
|
||||||
UpdatePermType(hst.EX11, m("/tmp/.X11-unix/X0"), acl.Read, acl.Write, acl.Execute).
|
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
|
// this op configures the container state and does not make calls during toContainer
|
||||||
}, &container.Params{
|
}, &container.Params{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
@ -107,7 +107,7 @@ func TestSpX11Op(t *testing.T) {
|
|||||||
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
|
call("stat", stub.ExpectArgs{"/tmp/.X11-unix/X0"}, (*stubFi)(nil), nil),
|
||||||
}, newI().
|
}, newI().
|
||||||
UpdatePermType(hst.EX11, m("/tmp/.X11-unix/X0"), acl.Read, acl.Write, acl.Execute).
|
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
|
// this op configures the container state and does not make calls during toContainer
|
||||||
}, &container.Params{
|
}, &container.Params{
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
|||||||
@ -136,7 +136,7 @@ func (s *Store) Segments() (iter.Seq[SegmentIdentity], int, error) {
|
|||||||
si.Err = &hst.AppError{Step: step, Err: err,
|
si.Err = &hst.AppError{Step: step, Err: err,
|
||||||
Msg: "skipped non-identity entry " + strconv.Quote(ent.Name())}
|
Msg: "skipped non-identity entry " + strconv.Quote(ent.Name())}
|
||||||
goto out
|
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,
|
si.Err = &hst.AppError{Step: step, Err: syscall.ERANGE,
|
||||||
Msg: "skipped out of bounds entry " + strconv.Itoa(v)}
|
Msg: "skipped out of bounds entry " + strconv.Itoa(v)}
|
||||||
goto out
|
goto out
|
||||||
|
|||||||
@ -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 {
|
{ID: (hst.ID)(bytes.Repeat([]byte{0xfe}, len(hst.ID{}))), PID: 0xbed, ShimPID: 0xfff, Config: func() *hst.Config {
|
||||||
template := hst.Template()
|
template := hst.Template()
|
||||||
template.Identity = hst.IdentityMax
|
template.Identity = hst.IdentityEnd
|
||||||
return template
|
return template
|
||||||
}(), Time: time.Unix(0, 0xcafebabe0)},
|
}(), Time: time.Unix(0, 0xcafebabe0)},
|
||||||
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
|
{ID: (hst.ID)(bytes.Repeat([]byte{0xfc}, len(hst.ID{}))), PID: 0x1bed, ShimPID: 0x1fff, Config: func() *hst.Config {
|
||||||
|
|||||||
@ -20,9 +20,10 @@ let
|
|||||||
|
|
||||||
cfg = config.environment.hakurei;
|
cfg = config.environment.hakurei;
|
||||||
|
|
||||||
getsubuid = fid: aid: 1000000 + fid * 10000 + aid;
|
# userid*userOffset + appStart + appid
|
||||||
getsubname = fid: aid: "u${toString fid}_a${toString aid}";
|
getsubuid = userid: appid: userid * 100000 + 10000 + appid;
|
||||||
getsubhome = fid: aid: "${cfg.stateDir}/u${toString fid}/a${toString aid}";
|
getsubname = userid: appid: "u${toString userid}_a${toString appid}";
|
||||||
|
getsubhome = userid: appid: "${cfg.stateDir}/u${toString userid}/a${toString appid}";
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@ -211,19 +211,19 @@ in
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/" "/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" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
|
(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) # not deterministic
|
||||||
(ent "/" ignore ignore ignore ignore ignore)
|
(ent "/" ignore ignore ignore ignore ignore)
|
||||||
(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 "/" "/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=1000004,gid=1000004")
|
(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 "/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/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
|
||||||
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
|
(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 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 "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
|
|||||||
@ -234,10 +234,10 @@ in
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/" "/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 "/" "/.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=1000003,gid=1000003")
|
(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 "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/full" "/dev/full" "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 "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
|
(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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,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=1000003,gid=1000003")
|
(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/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 "/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/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
|
||||||
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
|
(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/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/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")
|
(ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
|||||||
@ -138,7 +138,7 @@
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/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 "/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")
|
(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 "/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 "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "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 "/" "/.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=1000000,gid=1000000")
|
(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 "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/full" "/dev/full" "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 "/" "/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 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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,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=1000000,gid=1000000")
|
(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/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 "/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/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
|
||||||
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
|
(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 "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(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/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=1000000,gid=1000000")
|
(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=1000000,gid=1000000")
|
(ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
|||||||
@ -231,10 +231,10 @@ in
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/" "/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 "/" "/.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=1000005,gid=1000005")
|
(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 "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/full" "/dev/full" "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 "/" "/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 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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,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=1000005,gid=1000005")
|
(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/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 "/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/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
|
||||||
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
|
(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/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/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")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
|||||||
@ -230,10 +230,10 @@ in
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/" "/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 "/" "/.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=1000001,gid=1000001")
|
(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 "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/full" "/dev/full" "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 "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
|
(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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "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=1000001,gid=1000001")
|
(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=1000001,gid=1000001")
|
(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=1000001,gid=1000001")
|
(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=1000001,gid=1000001")
|
(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/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/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")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
|||||||
@ -238,10 +238,10 @@ in
|
|||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
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 "/" "/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 "/" "/.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=1000002,gid=1000002")
|
(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 "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/full" "/dev/full" "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 "/" "/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 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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,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=1000002,gid=1000002")
|
(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/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 "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
|
||||||
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
|
(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=1000002,gid=1000002")
|
(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 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 "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
|
|||||||
@ -26,7 +26,7 @@ def swaymsg(command: str = "", succeed=True, type="command"):
|
|||||||
|
|
||||||
|
|
||||||
def check_filter(check_offset, name, pname):
|
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")
|
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}"))
|
print(machine.succeed(f"hakurei-test -s {hash} filter {pid}"))
|
||||||
|
|
||||||
|
|||||||
16
test/test.py
16
test/test.py
@ -160,17 +160,17 @@ machine.succeed("pkill -9 mako")
|
|||||||
# Check revert type selection:
|
# Check revert type selection:
|
||||||
hakurei("-v run --wayland -X --dbus --pulse -u p0 foot && touch /tmp/p0-exit-ok")
|
hakurei("-v run --wayland -X --dbus --pulse -u p0 foot && touch /tmp/p0-exit-ok")
|
||||||
wait_for_window("p0@machine")
|
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")
|
hakurei("-v run --wayland -X --dbus --pulse -u p1 foot && touch /tmp/p1-exit-ok")
|
||||||
wait_for_window("p1@machine")
|
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.send_chars("exit\n")
|
||||||
machine.wait_for_file("/tmp/p1-exit-ok", timeout=15)
|
machine.wait_for_file("/tmp/p1-exit-ok", timeout=15)
|
||||||
# Verify acl is kept alive:
|
# 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.send_chars("exit\n")
|
||||||
machine.wait_for_file("/tmp/p0-exit-ok", timeout=15)
|
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:
|
# Check interrupt shim behaviour:
|
||||||
swaymsg("exec sh -c 'ne-foot; echo -n $? > /tmp/monitor-exit-code'")
|
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")
|
collect_state_ui("foot_wayland")
|
||||||
check_state("ne-foot", {"wayland": True})
|
check_state("ne-foot", {"wayland": True})
|
||||||
# Verify lack of acl on XDG_RUNTIME_DIR:
|
# 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.send_chars("exit\n")
|
||||||
machine.wait_until_fails("pgrep foot", timeout=5)
|
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):
|
# Test PulseAudio (hakurei does not support PipeWire yet):
|
||||||
swaymsg("exec pa-foot")
|
swaymsg("exec pa-foot")
|
||||||
@ -242,11 +242,11 @@ collect_state_ui("foot_direct")
|
|||||||
machine.wait_for_file("/var/tmp/direct-ok", timeout=15)
|
machine.wait_for_file("/var/tmp/direct-ok", timeout=15)
|
||||||
check_state("da-foot", {"wayland": True})
|
check_state("da-foot", {"wayland": True})
|
||||||
# Verify acl on XDG_RUNTIME_DIR:
|
# 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.send_chars("exit\n")
|
||||||
machine.wait_until_fails("pgrep foot", timeout=5)
|
machine.wait_until_fails("pgrep foot", timeout=5)
|
||||||
# Verify acl cleanup on XDG_RUNTIME_DIR:
|
# 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:
|
# Test syscall filter:
|
||||||
print(machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 strace-failure"))
|
print(machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 strace-failure"))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user