aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--internal/acl/acl.go84
-rw-r--r--internal/acl/acl_test.go136
-rw-r--r--internal/acl/libacl-helper.c87
-rw-r--r--internal/acl/libacl-helper.go40
-rw-r--r--internal/acl/libacl-helper.h24
-rw-r--r--internal/acl/libacl-helper_test.go47
-rw-r--r--internal/acl/perms.go26
-rw-r--r--internal/acl/perms_test.go20
-rw-r--r--internal/outcome/run_test.go32
-rw-r--r--internal/outcome/spcontainer.go10
-rw-r--r--internal/outcome/spcontainer_test.go10
-rw-r--r--internal/outcome/spdbus.go4
-rw-r--r--internal/outcome/spdbus_test.go6
-rw-r--r--internal/outcome/spruntime.go2
-rw-r--r--internal/outcome/spruntime_test.go8
-rw-r--r--internal/outcome/sptmpdir.go2
-rw-r--r--internal/outcome/sptmpdir_test.go2
-rw-r--r--internal/outcome/spwayland.go2
-rw-r--r--internal/outcome/spwayland_test.go2
-rw-r--r--internal/outcome/spx11.go2
-rw-r--r--internal/outcome/spx11_test.go4
-rw-r--r--internal/system/acl.go17
-rw-r--r--internal/system/acl_test.go100
-rw-r--r--internal/system/dispatcher.go6
-rw-r--r--internal/system/dispatcher_test.go4
-rw-r--r--internal/system/pipewire.go2
-rw-r--r--internal/system/pipewire_test.go2
-rw-r--r--internal/system/wayland.go2
-rw-r--r--internal/system/wayland_test.go4
29 files changed, 412 insertions, 275 deletions
diff --git a/internal/acl/acl.go b/internal/acl/acl.go
index 366ad533..7718ba3c 100644
--- a/internal/acl/acl.go
+++ b/internal/acl/acl.go
@@ -7,27 +7,89 @@ package acl
#include "libacl-helper.h"
*/
import "C"
+import "os"
+// Perm represents acl_perm_t.
type Perm C.acl_perm_t
const (
- Read Perm = C.ACL_READ
- Write Perm = C.ACL_WRITE
+ // Read represents ACL_READ.
+ Read Perm = C.ACL_READ
+ // Write represents ACL_WRITE.
+ Write Perm = C.ACL_WRITE
+ // Execute represents ACL_EXECUTE.
Execute Perm = C.ACL_EXECUTE
)
-// Update replaces ACL_USER entry with qualifier uid.
-func Update(name string, uid int, perms ...Perm) error {
- var p *Perm
- if len(perms) > 0 {
- p = &perms[0]
+// Status is the outcome of an ACL update operation.
+type Status = C.enum_hakurei_acl_status
+
+// An Error describes an error encountered during [Update].
+type Error struct {
+ // Pathname of the file to update ACL for.
+ Path string
+ // Function that returned the error.
+ Op Status
+ // Underlying errno.
+ Err error
+}
+
+// Unwrap returns an [os.PathError] describing e.
+func (e Error) Unwrap() error {
+ v := os.PathError{Path: e.Path, Err: e.Err}
+ switch e.Op {
+ case C.HAKUREI_ACL_OK:
+ return os.ErrInvalid
+
+ case C.HAKUREI_ACL_GET_FILE:
+ v.Op = "acl_get_file"
+ case C.HAKUREI_ACL_GET_TAG_TYPE:
+ v.Op = "acl_get_tag_type"
+ case C.HAKUREI_ACL_GET_QUALIFIER:
+ v.Op = "acl_get_qualifier"
+ case C.HAKUREI_ACL_DELETE_ENTRY:
+ v.Op = "acl_delete_entry"
+ case C.HAKUREI_ACL_CREATE_ENTRY:
+ v.Op = "acl_create_entry"
+ case C.HAKUREI_ACL_GET_PERMSET:
+ v.Op = "acl_get_permset"
+ case C.HAKUREI_ACL_ADD_PERM:
+ v.Op = "acl_add_perm"
+ case C.HAKUREI_ACL_SET_TAG_TYPE:
+ v.Op = "acl_set_tag_type"
+ case C.HAKUREI_ACL_SET_QUALIFIER:
+ v.Op = "acl_set_qualifier"
+ case C.HAKUREI_ACL_CALC_MASK:
+ v.Op = "acl_calc_mask"
+ case C.HAKUREI_ACL_VALID:
+ v.Op = "acl_valid"
+ case C.HAKUREI_ACL_SET_FILE:
+ v.Op = "acl_set_file"
+ case C.HAKUREI_ACL_GET_PERM:
+ v.Op = "acl_get_perm"
+ case C.HAKUREI_ACL_DUP:
+ v.Op = "acl_dup"
+
+ default: // unreachable
+ v.Op = "setfacl"
}
+ return &v
+}
+
+// Error returns the message of the resulting [os.PathError].
+func (e Error) Error() string {
+ return e.Unwrap().Error()
+}
- r, err := C.hakurei_acl_update_file_by_uid(
+// Update replaces ACL_USER entry with qualifier uid.
+func Update(name string, uid int, perms Perm) error {
+ r, err := C.hakurei_update_acl(
C.CString(name),
C.uid_t(uid),
- (*C.acl_perm_t)(p),
- C.size_t(len(perms)),
+ C.acl_perm_t(perms),
)
- return newAclPathError(name, int(r), err)
+ if r == C.HAKUREI_ACL_OK {
+ return nil
+ }
+ return &Error{name, r, err}
}
diff --git a/internal/acl/acl_test.go b/internal/acl/acl_test.go
index 60c4b702..6e84e832 100644
--- a/internal/acl/acl_test.go
+++ b/internal/acl/acl_test.go
@@ -22,7 +22,7 @@ const testFileName = "acl.test"
var (
uid = os.Geteuid()
- cred = int32(os.Geteuid())
+ cred = int32(uid)
)
func TestUpdate(t *testing.T) {
@@ -31,7 +31,7 @@ func TestUpdate(t *testing.T) {
if err := os.WriteFile(name, nil, 0); err != nil {
t.Fatal(err)
}
- if err := acl.Update(name, os.Geteuid()); errors.Is(err, syscall.ENOTSUP) {
+ if err := acl.Update(name, uid, 0); errors.Is(err, syscall.ENOTSUP) {
t.Skip(err)
}
}
@@ -60,7 +60,7 @@ func TestUpdate(t *testing.T) {
})
t.Run("default clear mask", func(t *testing.T) {
- if err := acl.Update(testFilePath, uid); err != nil {
+ if err := acl.Update(testFilePath, uid, 0); err != nil {
t.Fatalf("Update: error = %v", err)
}
if cur = getfacl(t, testFilePath); len(cur) != 4 {
@@ -69,7 +69,7 @@ func TestUpdate(t *testing.T) {
})
t.Run("default clear consistency", func(t *testing.T) {
- if err := acl.Update(testFilePath, uid); err != nil {
+ if err := acl.Update(testFilePath, uid, 0); err != nil {
t.Fatalf("Update: error = %v", err)
}
if val := getfacl(t, testFilePath); !reflect.DeepEqual(val, cur) {
@@ -77,34 +77,78 @@ func TestUpdate(t *testing.T) {
}
})
- testUpdate(t, testFilePath, "r--", cur, fAclPermRead, acl.Read)
- testUpdate(t, testFilePath, "-w-", cur, fAclPermWrite, acl.Write)
- testUpdate(t, testFilePath, "--x", cur, fAclPermExecute, acl.Execute)
- testUpdate(t, testFilePath, "-wx", cur, fAclPermWrite|fAclPermExecute, acl.Write, acl.Execute)
- testUpdate(t, testFilePath, "r-x", cur, fAclPermRead|fAclPermExecute, acl.Read, acl.Execute)
- testUpdate(t, testFilePath, "rw-", cur, fAclPermRead|fAclPermWrite, acl.Read, acl.Write)
- testUpdate(t, testFilePath, "rwx", cur, fAclPermRead|fAclPermWrite|fAclPermExecute, acl.Read, acl.Write, acl.Execute)
+ testUpdate(t, testFilePath, "r--", "", cur, acl.Read, true)
+ testUpdate(t, testFilePath, "-w-", "", cur, acl.Write, true)
+ testUpdate(t, testFilePath, "--x", "", cur, acl.Execute, true)
+
+ testUpdate(
+ t, testFilePath, "-wx", "", cur,
+ acl.Write|acl.Execute,
+ true,
+ )
+ testUpdate(
+ t, testFilePath, "r-x", "", cur,
+ acl.Read|acl.Execute,
+ true,
+ )
+ testUpdate(
+ t, testFilePath, "rw-", "", cur,
+ acl.Read|acl.Write,
+ true,
+ )
+ testUpdate(
+ t, testFilePath, "rwx", "", cur,
+ acl.Read|acl.Write|acl.Execute,
+ true,
+ )
+
+ for i := range 16 {
+ testUpdate(
+ t, testFilePath, "r-x", " "+strconv.Itoa(i), cur,
+ acl.Read|acl.Execute,
+ false,
+ )
+ }
+
+ testUpdate(
+ t, testFilePath, "rwx", " cleanup", cur,
+ acl.Read|acl.Write|acl.Execute,
+ true,
+ )
}
-func testUpdate(t *testing.T, testFilePath, name string, cur []*getFAclResp, val fAclPerm, perms ...acl.Perm) {
- t.Run(name, func(t *testing.T) {
- t.Cleanup(func() {
- if err := acl.Update(testFilePath, uid); err != nil {
- t.Fatalf("Update: error = %v", err)
- }
- if v := getfacl(t, testFilePath); !reflect.DeepEqual(v, cur) {
- t.Fatalf("Update: %v, want %v", v, cur)
- }
- })
+func testUpdate(
+ t *testing.T,
+ testFilePath, name, suffix string,
+ cur []*getFACLResp,
+ perms acl.Perm,
+ cleanup bool,
+) {
+ t.Run(name+suffix, func(t *testing.T) {
+ if cleanup {
+ t.Cleanup(func() {
+ if err := acl.Update(testFilePath, uid, 0); err != nil {
+ t.Fatalf("Update: error = %v", err)
+ }
+ if v := getfacl(t, testFilePath); !reflect.DeepEqual(v, cur) {
+ t.Fatalf("Update: %v, want %v", v, cur)
+ }
+ })
+ }
- if err := acl.Update(testFilePath, uid, perms...); err != nil {
+ if err := acl.Update(testFilePath, uid, perms); err != nil {
t.Fatalf("Update: error = %v", err)
}
r := respByCred(getfacl(t, testFilePath), fAclTypeUser, cred)
if r == nil {
t.Fatalf("Update did not add an ACL entry")
}
- if !r.equals(fAclTypeUser, cred, val) {
+
+ if !r.equals(&getFACLResp{
+ typ: fAclTypeUser,
+ cred: cred,
+ val: perms,
+ }) {
t.Fatalf("Update(%s) = %s", name, r)
}
})
@@ -113,31 +157,24 @@ func testUpdate(t *testing.T, testFilePath, name string, cur []*getFAclResp, val
type (
getFAclInvocation struct {
cmd *exec.Cmd
- val []*getFAclResp
+ val []*getFACLResp
pe []error
}
- getFAclResp struct {
+ getFACLResp struct {
typ fAclType
cred int32
- val fAclPerm
+ val acl.Perm
raw []byte
}
- fAclPerm uintptr
fAclType uint8
)
const fAclBufSize = 16
const (
- fAclPermRead fAclPerm = 1 << iota
- fAclPermWrite
- fAclPermExecute
-)
-
-const (
fAclTypeUser fAclType = iota
fAclTypeGroup
fAclTypeMask
@@ -149,7 +186,13 @@ func (c *getFAclInvocation) run(name string) error {
panic("attempted to run twice")
}
- c.cmd = exec.Command("getfacl", "--omit-header", "--absolute-names", "--numeric", name)
+ c.cmd = exec.Command(
+ "getfacl",
+ "--omit-header",
+ "--absolute-names",
+ "--numeric",
+ name,
+ )
c.cmd.Stderr = os.Stderr
scanErr := make(chan error, 1)
@@ -166,18 +209,17 @@ func (c *getFAclInvocation) run(name string) error {
return errors.Join(<-scanErr, c.cmd.Wait())
}
-func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) {
- c.val = make([]*getFAclResp, 0, 4+fAclBufSize)
+func (c *getFAclInvocation) parse(r io.Reader, scanErr chan error) {
+ c.val = make([]*getFACLResp, 0, 4+fAclBufSize)
- s := bufio.NewScanner(pipe)
+ s := bufio.NewScanner(r)
for s.Scan() {
fields := bytes.SplitN(s.Bytes(), []byte{':'}, 3)
if len(fields) != 3 {
continue
}
- resp := getFAclResp{}
-
+ var resp getFACLResp
switch string(fields[0]) {
case "user":
resp.typ = fAclTypeUser
@@ -213,7 +255,7 @@ func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) {
} else {
switch fields[2][0] {
case 'r':
- resp.val |= fAclPermRead
+ resp.val |= acl.Read
case '-':
default:
c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][0]))
@@ -221,7 +263,7 @@ func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) {
}
switch fields[2][1] {
case 'w':
- resp.val |= fAclPermWrite
+ resp.val |= acl.Write
case '-':
default:
c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][1]))
@@ -229,7 +271,7 @@ func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) {
}
switch fields[2][2] {
case 'x':
- resp.val |= fAclPermExecute
+ resp.val |= acl.Execute
case '-':
default:
c.pe = append(c.pe, fmt.Errorf("invalid perm %v", fields[2][2]))
@@ -244,7 +286,7 @@ func (c *getFAclInvocation) parse(pipe io.Reader, scanErr chan error) {
scanErr <- s.Err()
}
-func (r *getFAclResp) String() string {
+func (r *getFACLResp) String() string {
if r.raw != nil && len(r.raw) > 0 {
return string(r.raw)
}
@@ -252,11 +294,11 @@ func (r *getFAclResp) String() string {
return "(user-initialised resp value)"
}
-func (r *getFAclResp) equals(typ fAclType, cred int32, val fAclPerm) bool {
- return r.typ == typ && r.cred == cred && r.val == val
+func (r *getFACLResp) equals(v *getFACLResp) bool {
+ return r.typ == v.typ && r.cred == v.cred && r.val == v.val
}
-func getfacl(t *testing.T, name string) []*getFAclResp {
+func getfacl(t *testing.T, name string) []*getFACLResp {
c := new(getFAclInvocation)
if err := c.run(name); err != nil {
t.Fatalf("getfacl: error = %v", err)
@@ -267,7 +309,7 @@ func getfacl(t *testing.T, name string) []*getFAclResp {
return c.val
}
-func respByCred(v []*getFAclResp, typ fAclType, cred int32) *getFAclResp {
+func respByCred(v []*getFACLResp, typ fAclType, cred int32) *getFACLResp {
j := -1
for i, r := range v {
if r.typ == typ && r.cred == cred {
diff --git a/internal/acl/libacl-helper.c b/internal/acl/libacl-helper.c
index 259dfb2b..065c1928 100644
--- a/internal/acl/libacl-helper.c
+++ b/internal/acl/libacl-helper.c
@@ -4,18 +4,22 @@
#include <stdlib.h>
#include <sys/acl.h>
-int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
- acl_perm_t *perms, size_t plen) {
- int ret;
+enum hakurei_acl_status hakurei_update_acl(
+ const char *path_p,
+ uid_t uid,
+ acl_perm_t perms) {
+ enum hakurei_acl_status ret;
+
bool v;
int i;
- acl_t acl;
+ acl_t acl, acl_d = NULL;
acl_entry_t entry;
acl_tag_t tag_type;
void *qualifier_p;
acl_permset_t permset;
+ acl_perm_t has_perms;
- ret = -1; /* acl_get_file */
+ ret = HAKUREI_ACL_GET_FILE;
acl = acl_get_file(path_p, ACL_TYPE_ACCESS);
if (acl == NULL)
goto out;
@@ -23,13 +27,13 @@ int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
/* prune entries by uid */
for (i = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); i == 1;
i = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
- ret = -2; /* acl_get_tag_type */
+ ret = HAKUREI_ACL_GET_TAG_TYPE;
if (acl_get_tag_type(entry, &tag_type) != 0)
goto out;
if (tag_type != ACL_USER)
continue;
- ret = -3; /* acl_get_qualifier */
+ ret = HAKUREI_ACL_GET_QUALIFIER;
qualifier_p = acl_get_qualifier(entry);
if (qualifier_p == NULL)
goto out;
@@ -39,52 +43,91 @@ int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
if (!v)
continue;
- ret = -4; /* acl_delete_entry */
+ ret = HAKUREI_ACL_GET_PERMSET;
+ if (acl_get_permset(entry, &permset) != 0)
+ goto out;
+
+ if (perms == 0)
+ goto delete;
+
+ /* this is quite ugly, but the standard makes it impossible to directly
+ * obtain these bits */
+ has_perms = 0;
+#define COPY_PERM_BIT(perm) \
+ do { \
+ ret = HAKUREI_ACL_GET_PERM; \
+ i = acl_get_perm(permset, perm); \
+ if (i < 0) \
+ goto out; \
+ if (i > 0) \
+ has_perms |= perm; \
+ } while (0)
+ COPY_PERM_BIT(ACL_READ);
+ COPY_PERM_BIT(ACL_WRITE);
+ COPY_PERM_BIT(ACL_EXECUTE);
+
+ if (perms == has_perms) {
+ ret = HAKUREI_ACL_DUP;
+ acl_d = acl_dup(acl);
+ if (acl_d == NULL)
+ goto out;
+
+ ret = HAKUREI_ACL_CALC_MASK;
+ if (acl_calc_mask(&acl_d) != 0)
+ goto out;
+
+ ret = HAKUREI_ACL_OK;
+ if (acl_cmp(acl, acl_d) == 0)
+ goto out;
+ }
+
+ delete:
+ ret = HAKUREI_ACL_DELETE_ENTRY;
if (acl_delete_entry(acl, entry) != 0)
goto out;
}
- if (plen == 0)
+ if (perms == 0)
goto set;
- ret = -5; /* acl_create_entry */
+ ret = HAKUREI_ACL_CREATE_ENTRY;
if (acl_create_entry(&acl, &entry) != 0)
goto out;
- ret = -6; /* acl_get_permset */
+ ret = HAKUREI_ACL_GET_PERMSET;
if (acl_get_permset(entry, &permset) != 0)
goto out;
- ret = -7; /* acl_add_perm */
- for (i = 0; i < plen; i++) {
- if (acl_add_perm(permset, perms[i]) != 0)
- goto out;
- }
+ ret = HAKUREI_ACL_ADD_PERM;
+ if (acl_add_perm(permset, perms) != 0)
+ goto out;
- ret = -8; /* acl_set_tag_type */
+ ret = HAKUREI_ACL_SET_TAG_TYPE;
if (acl_set_tag_type(entry, ACL_USER) != 0)
goto out;
- ret = -9; /* acl_set_qualifier */
+ ret = HAKUREI_ACL_SET_QUALIFIER;
if (acl_set_qualifier(entry, (void *)&uid) != 0)
goto out;
set:
- ret = -10; /* acl_calc_mask */
+ ret = HAKUREI_ACL_CALC_MASK;
if (acl_calc_mask(&acl) != 0)
goto out;
- ret = -11; /* acl_valid */
+ ret = HAKUREI_ACL_VALID;
if (acl_valid(acl) != 0)
goto out;
- ret = -12; /* acl_set_file */
+ ret = HAKUREI_ACL_SET_FILE;
if (acl_set_file(path_p, ACL_TYPE_ACCESS, acl) == 0)
- ret = 0;
+ ret = HAKUREI_ACL_OK;
out:
free((void *)path_p);
if (acl != NULL)
acl_free((void *)acl);
+ if (acl_d != NULL)
+ acl_free((void *)acl_d);
return ret;
}
diff --git a/internal/acl/libacl-helper.go b/internal/acl/libacl-helper.go
deleted file mode 100644
index 22575296..00000000
--- a/internal/acl/libacl-helper.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package acl
-
-import "os"
-
-func newAclPathError(name string, r int, err error) error {
- pathError := &os.PathError{Path: name, Err: err}
- switch r {
- case 0:
- return nil
-
- case -1:
- pathError.Op = "acl_get_file"
- case -2:
- pathError.Op = "acl_get_tag_type"
- case -3:
- pathError.Op = "acl_get_qualifier"
- case -4:
- pathError.Op = "acl_delete_entry"
- case -5:
- pathError.Op = "acl_create_entry"
- case -6:
- pathError.Op = "acl_get_permset"
- case -7:
- pathError.Op = "acl_add_perm"
- case -8:
- pathError.Op = "acl_set_tag_type"
- case -9:
- pathError.Op = "acl_set_qualifier"
- case -10:
- pathError.Op = "acl_calc_mask"
- case -11:
- pathError.Op = "acl_valid"
- case -12:
- pathError.Op = "acl_set_file"
-
- default: // unreachable
- pathError.Op = "setfacl"
- }
- return pathError
-}
diff --git a/internal/acl/libacl-helper.h b/internal/acl/libacl-helper.h
index b86eb170..753e1109 100644
--- a/internal/acl/libacl-helper.h
+++ b/internal/acl/libacl-helper.h
@@ -1,4 +1,24 @@
#include <sys/acl.h>
-int hakurei_acl_update_file_by_uid(const char *path_p, uid_t uid,
- acl_perm_t *perms, size_t plen);
+enum hakurei_acl_status {
+ HAKUREI_ACL_OK,
+ HAKUREI_ACL_GET_FILE,
+ HAKUREI_ACL_GET_TAG_TYPE,
+ HAKUREI_ACL_GET_QUALIFIER,
+ HAKUREI_ACL_DELETE_ENTRY,
+ HAKUREI_ACL_CREATE_ENTRY,
+ HAKUREI_ACL_GET_PERMSET,
+ HAKUREI_ACL_ADD_PERM,
+ HAKUREI_ACL_SET_TAG_TYPE,
+ HAKUREI_ACL_SET_QUALIFIER,
+ HAKUREI_ACL_CALC_MASK,
+ HAKUREI_ACL_VALID,
+ HAKUREI_ACL_SET_FILE,
+ HAKUREI_ACL_GET_PERM,
+ HAKUREI_ACL_DUP,
+};
+
+enum hakurei_acl_status hakurei_update_acl(
+ const char *path_p,
+ uid_t uid,
+ acl_perm_t perms);
diff --git a/internal/acl/libacl-helper_test.go b/internal/acl/libacl-helper_test.go
index 13d23a3c..05c43639 100644
--- a/internal/acl/libacl-helper_test.go
+++ b/internal/acl/libacl-helper_test.go
@@ -1,4 +1,4 @@
-package acl
+package acl_test
import (
"os"
@@ -7,9 +7,12 @@ import (
"testing"
"hakurei.app/container"
+ "hakurei.app/internal/acl"
)
-func TestNewAclPathError(t *testing.T) {
+func TestError(t *testing.T) {
+ t.Parallel()
+
testCases := []struct {
name string
path string
@@ -17,43 +20,51 @@ func TestNewAclPathError(t *testing.T) {
err error
want error
}{
- {"nil", container.Nonexistent, 0, syscall.ENOTRECOVERABLE, nil},
+ {"nil", container.Nonexistent, 0, syscall.ENOTRECOVERABLE, os.ErrInvalid},
- {"acl_get_file", container.Nonexistent, -1, syscall.ENOTRECOVERABLE,
+ {"acl_get_file", container.Nonexistent, 1, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_get_file", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_get_tag_type", container.Nonexistent, -2, syscall.ENOTRECOVERABLE,
+ {"acl_get_tag_type", container.Nonexistent, 2, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_get_tag_type", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_get_qualifier", container.Nonexistent, -3, syscall.ENOTRECOVERABLE,
+ {"acl_get_qualifier", container.Nonexistent, 3, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_get_qualifier", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_delete_entry", container.Nonexistent, -4, syscall.ENOTRECOVERABLE,
+ {"acl_delete_entry", container.Nonexistent, 4, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_delete_entry", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_create_entry", container.Nonexistent, -5, syscall.ENOTRECOVERABLE,
+ {"acl_create_entry", container.Nonexistent, 5, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_create_entry", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_get_permset", container.Nonexistent, -6, syscall.ENOTRECOVERABLE,
+ {"acl_get_permset", container.Nonexistent, 6, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_get_permset", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_add_perm", container.Nonexistent, -7, syscall.ENOTRECOVERABLE,
+ {"acl_add_perm", container.Nonexistent, 7, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_add_perm", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_set_tag_type", container.Nonexistent, -8, syscall.ENOTRECOVERABLE,
+ {"acl_set_tag_type", container.Nonexistent, 8, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_set_tag_type", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_set_qualifier", container.Nonexistent, -9, syscall.ENOTRECOVERABLE,
+ {"acl_set_qualifier", container.Nonexistent, 9, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_set_qualifier", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_calc_mask", container.Nonexistent, -10, syscall.ENOTRECOVERABLE,
+ {"acl_calc_mask", container.Nonexistent, 10, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_calc_mask", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_valid", container.Nonexistent, -11, syscall.ENOTRECOVERABLE,
+ {"acl_valid", container.Nonexistent, 11, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_valid", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl_set_file", container.Nonexistent, -12, syscall.ENOTRECOVERABLE,
+ {"acl_set_file", container.Nonexistent, 12, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "acl_set_file", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
+ {"acl_get_perm", container.Nonexistent, 13, syscall.ENOTRECOVERABLE,
+ &os.PathError{Op: "acl_get_perm", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
+ {"acl_dup", container.Nonexistent, 14, syscall.ENOTRECOVERABLE,
+ &os.PathError{Op: "acl_dup", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
- {"acl", container.Nonexistent, -13, syscall.ENOTRECOVERABLE,
+ {"acl", container.Nonexistent, 15, syscall.ENOTRECOVERABLE,
&os.PathError{Op: "setfacl", Path: container.Nonexistent, Err: syscall.ENOTRECOVERABLE}},
{"invalid", container.Nonexistent, -0xdead, nil,
&os.PathError{Op: "setfacl", Path: container.Nonexistent}},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- err := newAclPathError(tc.path, tc.r, tc.err)
+ err := acl.Error{
+ Path: tc.path,
+ Op: acl.Status(tc.r),
+ Err: tc.err,
+ }.Unwrap()
if !reflect.DeepEqual(err, tc.want) {
- t.Errorf("newAclPathError: %v, want %v", err, tc.want)
+ t.Errorf("Unwrap: %v, want %v", err, tc.want)
}
})
}
diff --git a/internal/acl/perms.go b/internal/acl/perms.go
index fbc99e82..829b134f 100644
--- a/internal/acl/perms.go
+++ b/internal/acl/perms.go
@@ -1,18 +1,18 @@
package acl
-type Perms []Perm
+import "unsafe"
-func (ps Perms) String() string {
- var s = []byte("---")
- for _, p := range ps {
- switch p {
- case Read:
- s[0] = 'r'
- case Write:
- s[1] = 'w'
- case Execute:
- s[2] = 'x'
- }
+// String returns a text representation of perms.
+func (perms Perm) String() string {
+ buf := []byte{'-', '-', '-'}
+ if perms&Read != 0 {
+ buf[0] = 'r'
}
- return string(s)
+ if perms&Write != 0 {
+ buf[1] = 'w'
+ }
+ if perms&Execute != 0 {
+ buf[2] = 'x'
+ }
+ return unsafe.String(unsafe.SliceData(buf), len(buf))
}
diff --git a/internal/acl/perms_test.go b/internal/acl/perms_test.go
index 3920046d..9fa24dc8 100644
--- a/internal/acl/perms_test.go
+++ b/internal/acl/perms_test.go
@@ -7,18 +7,20 @@ import (
)
func TestPerms(t *testing.T) {
+ t.Parallel()
+
testCases := []struct {
name string
- perms acl.Perms
+ perms acl.Perm
}{
- {"---", acl.Perms{}},
- {"r--", acl.Perms{acl.Read}},
- {"-w-", acl.Perms{acl.Write}},
- {"--x", acl.Perms{acl.Execute}},
- {"rw-", acl.Perms{acl.Read, acl.Read, acl.Write}},
- {"r-x", acl.Perms{acl.Read, acl.Execute, acl.Execute}},
- {"-wx", acl.Perms{acl.Write, acl.Write, acl.Execute, acl.Execute}},
- {"rwx", acl.Perms{acl.Read, acl.Write, acl.Execute}},
+ {"---", 0},
+ {"r--", acl.Read},
+ {"-w-", acl.Write},
+ {"--x", acl.Execute},
+ {"rw-", acl.Read | acl.Write},
+ {"r-x", acl.Read | acl.Execute},
+ {"-wx", acl.Write | acl.Execute},
+ {"rwx", acl.Read | acl.Write | acl.Execute},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
diff --git a/internal/outcome/run_test.go b/internal/outcome/run_test.go
index a1d83ec9..e4e33dca 100644
--- a/internal/outcome/run_test.go
+++ b/internal/outcome/run_test.go
@@ -48,13 +48,13 @@ func TestOutcomeRun(t *testing.T) {
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).
+ UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/9"), acl.Read|acl.Write|acl.Execute).
// spTmpdirOp
Ensure(m("/tmp/hakurei.0/tmpdir"), 0700).
UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
Ensure(m("/tmp/hakurei.0/tmpdir/9"), 01700).
- UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read, acl.Write, acl.Execute).
+ UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read|acl.Write|acl.Execute).
// instance
Ephemeral(system.Process, m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 0711).
@@ -84,13 +84,13 @@ func TestOutcomeRun(t *testing.T) {
"unix:path=/var/run/dbus/system_bus_socket",
"/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/system_bus_socket",
},
- ).UpdatePerm(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bus"), acl.Read, acl.Write).
- UpdatePerm(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/system_bus_socket"), acl.Read, acl.Write).
+ ).UpdatePerm(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bus"), acl.Read|acl.Write).
+ UpdatePerm(m("/tmp/hakurei.0/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/system_bus_socket"), acl.Read|acl.Write).
// spFilesystemOp
Ensure(m("/var/lib/hakurei/u0"), 0700).
UpdatePermType(system.User, m("/var/lib/hakurei/u0"), acl.Execute).
- UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"), acl.Read, acl.Write, acl.Execute), &container.Params{
+ UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"), acl.Read|acl.Write|acl.Execute), &container.Params{
Dir: m("/data/data/org.chromium.Chromium"),
Env: []string{
@@ -205,11 +205,11 @@ func TestOutcomeRun(t *testing.T) {
Ensure(m("/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/tmp/hakurei.0/runtime/0"), 0700).
- UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/0"), acl.Read, acl.Write, acl.Execute).
+ UpdatePermType(system.User, m("/tmp/hakurei.0/runtime/0"), acl.Read|acl.Write|acl.Execute).
Ensure(m("/tmp/hakurei.0/tmpdir"), 0700).
UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
Ensure(m("/tmp/hakurei.0/tmpdir/0"), 01700).
- UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/0"), acl.Read, acl.Write, acl.Execute), &container.Params{
+ UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/0"), acl.Read|acl.Write|acl.Execute), &container.Params{
Dir: m("/home/chronos"),
Path: m("/run/current-system/sw/bin/zsh"),
@@ -329,9 +329,9 @@ func TestOutcomeRun(t *testing.T) {
}, 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).
+ 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/tmpdir"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
- Ensure(m("/tmp/hakurei.0/tmpdir/9"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read, acl.Write, acl.Execute).
+ Ensure(m("/tmp/hakurei.0/tmpdir/9"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/9"), acl.Read|acl.Write|acl.Execute).
Ephemeral(system.Process, m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c"), 0711).
Wayland(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
PipeWire(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/pipewire"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c").
@@ -371,8 +371,8 @@ func TestOutcomeRun(t *testing.T) {
"unix:path=/var/run/dbus/system_bus_socket",
"/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket",
}).
- UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus"), acl.Read, acl.Write).
- UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket"), acl.Read, acl.Write), &container.Params{
+ UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus"), acl.Read|acl.Write).
+ UpdatePerm(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket"), acl.Read|acl.Write), &container.Params{
Dir: m("/home/chronos"),
Path: m("/run/current-system/sw/bin/zsh"),
@@ -480,12 +480,12 @@ func TestOutcomeRun(t *testing.T) {
}, 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).
+ 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/tmpdir"), 0700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir"), acl.Execute).
- Ensure(m("/tmp/hakurei.0/tmpdir/1"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/1"), acl.Read, acl.Write, acl.Execute).
+ Ensure(m("/tmp/hakurei.0/tmpdir/1"), 01700).UpdatePermType(system.User, m("/tmp/hakurei.0/tmpdir/1"), acl.Read|acl.Write|acl.Execute).
Ensure(m("/run/user/1971"), 0700).UpdatePermType(system.User, m("/run/user/1971"), acl.Execute). // this is ordered as is because the previous Ensure only calls mkdir if XDG_RUNTIME_DIR is unset
Ensure(m("/run/user/1971/hakurei"), 0700).UpdatePermType(system.User, m("/run/user/1971/hakurei"), acl.Execute).
- UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read, acl.Write, acl.Execute).
+ UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read|acl.Write|acl.Execute).
Ephemeral(system.Process, m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1"), 0711).
PipeWire(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/pipewire"), "org.chromium.Chromium", "8e2c76b066dabe574cf073bdb46eb5c1").
MustProxyDBus(&hst.BusConfig{
@@ -515,8 +515,8 @@ func TestOutcomeRun(t *testing.T) {
"unix:path=/var/run/dbus/system_bus_socket",
"/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket",
}).
- UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), acl.Read, acl.Write).
- UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket"), acl.Read, acl.Write), &container.Params{
+ UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), acl.Read|acl.Write).
+ UpdatePerm(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket"), acl.Read|acl.Write), &container.Params{
Uid: 1971,
Gid: 100,
diff --git a/internal/outcome/spcontainer.go b/internal/outcome/spcontainer.go
index bfa5dbdc..0ddc10ac 100644
--- a/internal/outcome/spcontainer.go
+++ b/internal/outcome/spcontainer.go
@@ -354,17 +354,17 @@ func flattenExtraPerms(sys *system.I, extraPerms []hst.ExtraPermConfig) {
sys.Ensure(p.Path, 0700)
}
- perms := make(acl.Perms, 0, 3)
+ var perms acl.Perm
if p.Read {
- perms = append(perms, acl.Read)
+ perms |= acl.Read
}
if p.Write {
- perms = append(perms, acl.Write)
+ perms |= acl.Write
}
if p.Execute {
- perms = append(perms, acl.Execute)
+ perms |= acl.Execute
}
- sys.UpdatePermType(system.User, p.Path, perms...)
+ sys.UpdatePermType(system.User, p.Path, perms)
}
}
diff --git a/internal/outcome/spcontainer_test.go b/internal/outcome/spcontainer_test.go
index 7dd47735..d9436cb4 100644
--- a/internal/outcome/spcontainer_test.go
+++ b/internal/outcome/spcontainer_test.go
@@ -313,7 +313,7 @@ func TestSpFilesystemOp(t *testing.T) {
UpdatePermType(system.User, m("/var/lib/hakurei/u0"),
acl.Execute).
UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"),
- acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
+ acl.Read|acl.Write|acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
state.filesystem = append(configSmall.Container.Filesystem, hst.FilesystemConfigJSON{})
})), []stub.Call{
// this op configures the container state and does not make calls during toContainer
@@ -346,7 +346,7 @@ func TestSpFilesystemOp(t *testing.T) {
UpdatePermType(system.User, m("/var/lib/hakurei/u0"),
acl.Execute).
UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"),
- acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
+ acl.Read|acl.Write|acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
state.filesystem = configSmall.Container.Filesystem
})), []stub.Call{
// this op configures the container state and does not make calls during toContainer
@@ -401,7 +401,7 @@ func TestSpFilesystemOp(t *testing.T) {
UpdatePermType(system.User, m("/var/lib/hakurei/u0"),
acl.Execute).
UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"),
- acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
+ acl.Read|acl.Write|acl.Execute), nil, nil, insertsOps(needsApplyState(func(state *outcomeStateParams) {
state.filesystem = config.Container.Filesystem[1:]
})), []stub.Call{
// this op configures the container state and does not make calls during toContainer
@@ -445,14 +445,14 @@ func TestFlattenExtraPerms(t *testing.T) {
UpdatePermType(system.User, m("/var/lib/hakurei/u0"),
acl.Execute).
UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"),
- acl.Read, acl.Write, acl.Execute)},
+ acl.Read|acl.Write|acl.Execute)},
{"template", hst.Template().ExtraPerms, newI().
Ensure(m("/var/lib/hakurei/u0"), 0700).
UpdatePermType(system.User, m("/var/lib/hakurei/u0"),
acl.Execute).
UpdatePermType(system.User, m("/var/lib/hakurei/u0/org.chromium.Chromium"),
- acl.Read, acl.Write, acl.Execute)},
+ acl.Read|acl.Write|acl.Execute)},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
diff --git a/internal/outcome/spdbus.go b/internal/outcome/spdbus.go
index a50f9cd2..c45dde6c 100644
--- a/internal/outcome/spdbus.go
+++ b/internal/outcome/spdbus.go
@@ -38,10 +38,10 @@ func (s *spDBusOp) toSystem(state *outcomeStateSys) error {
return err
}
- state.sys.UpdatePerm(sessionPath, acl.Read, acl.Write)
+ state.sys.UpdatePerm(sessionPath, acl.Read|acl.Write)
if state.systemBus != nil {
s.ProxySystem = true
- state.sys.UpdatePerm(systemPath, acl.Read, acl.Write)
+ state.sys.UpdatePerm(systemPath, acl.Read|acl.Write)
}
return nil
}
diff --git a/internal/outcome/spdbus_test.go b/internal/outcome/spdbus_test.go
index 6f357193..0e4704a8 100644
--- a/internal/outcome/spdbus_test.go
+++ b/internal/outcome/spdbus_test.go
@@ -89,7 +89,7 @@ func TestSpDBusOp(t *testing.T) {
); err != nil {
t.Fatalf("cannot prepare sys: %v", err)
}
- sys.UpdatePerm(m(wantInstancePrefix+"/bus"), acl.Read, acl.Write)
+ sys.UpdatePerm(m(wantInstancePrefix+"/bus"), acl.Read|acl.Write)
return sys
}(), sysUsesInstance(nil), nil, insertsOps(afterSpRuntimeOp(nil)), []stub.Call{
// this op configures the container state and does not make calls during toContainer
@@ -171,8 +171,8 @@ func TestSpDBusOp(t *testing.T) {
); err != nil {
t.Fatalf("cannot prepare sys: %v", err)
}
- sys.UpdatePerm(m(wantInstancePrefix+"/bus"), acl.Read, acl.Write).
- UpdatePerm(m(wantInstancePrefix+"/system_bus_socket"), acl.Read, acl.Write)
+ sys.UpdatePerm(m(wantInstancePrefix+"/bus"), acl.Read|acl.Write).
+ UpdatePerm(m(wantInstancePrefix+"/system_bus_socket"), acl.Read|acl.Write)
return sys
}(), sysUsesInstance(nil), nil, insertsOps(afterSpRuntimeOp(nil)), []stub.Call{
// this op configures the container state and does not make calls during toContainer
diff --git a/internal/outcome/spruntime.go b/internal/outcome/spruntime.go
index c08bfe81..9d36f252 100644
--- a/internal/outcome/spruntime.go
+++ b/internal/outcome/spruntime.go
@@ -79,7 +79,7 @@ func (s *spRuntimeOp) toSystem(state *outcomeStateSys) error {
state.sys.Ensure(runtimeDir, 0700)
state.sys.UpdatePermType(system.User, runtimeDir, acl.Execute)
state.sys.Ensure(runtimeDirInst, 0700)
- state.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
+ state.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read|acl.Write|acl.Execute)
}
if state.et&hst.EWayland != 0 {
diff --git a/internal/outcome/spruntime_test.go b/internal/outcome/spruntime_test.go
index 25f2684c..618fc7ac 100644
--- a/internal/outcome/spruntime_test.go
+++ b/internal/outcome/spruntime_test.go
@@ -36,7 +36,7 @@ func TestSpRuntimeOp(t *testing.T) {
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), 0700).
- UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(nil), []stub.Call{
+ UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read|acl.Write|acl.Execute), 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).
@@ -64,7 +64,7 @@ func TestSpRuntimeOp(t *testing.T) {
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), 0700).
- UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(nil), []stub.Call{
+ UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read|acl.Write|acl.Execute), 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).
@@ -92,7 +92,7 @@ func TestSpRuntimeOp(t *testing.T) {
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), 0700).
- UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(nil), []stub.Call{
+ UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read|acl.Write|acl.Execute), 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).
@@ -116,7 +116,7 @@ func TestSpRuntimeOp(t *testing.T) {
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime"), 0700).
UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime"), acl.Execute).
Ensure(m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), 0700).
- UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(nil), []stub.Call{
+ UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/runtime/9"), acl.Read|acl.Write|acl.Execute), 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/outcome/sptmpdir.go b/internal/outcome/sptmpdir.go
index daa6f0de..3acb069f 100644
--- a/internal/outcome/sptmpdir.go
+++ b/internal/outcome/sptmpdir.go
@@ -22,7 +22,7 @@ func (s spTmpdirOp) toSystem(state *outcomeStateSys) error {
state.sys.Ensure(tmpdir, 0700)
state.sys.UpdatePermType(system.User, tmpdir, acl.Execute)
state.sys.Ensure(tmpdirInst, 01700)
- state.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
+ state.sys.UpdatePermType(system.User, tmpdirInst, acl.Read|acl.Write|acl.Execute)
}
return nil
}
diff --git a/internal/outcome/sptmpdir_test.go b/internal/outcome/sptmpdir_test.go
index 620f51b0..2073ad81 100644
--- a/internal/outcome/sptmpdir_test.go
+++ b/internal/outcome/sptmpdir_test.go
@@ -24,7 +24,7 @@ func TestSpTmpdirOp(t *testing.T) {
Ensure(m("/proc/nonexistent/tmp/hakurei.0/tmpdir"), 0700).
UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/tmpdir"), acl.Execute).
Ensure(m("/proc/nonexistent/tmp/hakurei.0/tmpdir/9"), 01700).
- UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/tmpdir/9"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(nil), []stub.Call{
+ UpdatePermType(system.User, m("/proc/nonexistent/tmp/hakurei.0/tmpdir/9"), acl.Read|acl.Write|acl.Execute), 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/outcome/spwayland.go b/internal/outcome/spwayland.go
index 3c60ff10..db79d1d2 100644
--- a/internal/outcome/spwayland.go
+++ b/internal/outcome/spwayland.go
@@ -49,7 +49,7 @@ func (s *spWaylandOp) toSystem(state *outcomeStateSys) error {
state.msg.Verbose("direct wayland access, PROCEED WITH CAUTION")
state.ensureRuntimeDir()
s.SocketPath = socketPath
- state.sys.UpdatePermType(hst.EWayland, socketPath, acl.Read, acl.Write, acl.Execute)
+ state.sys.UpdatePermType(hst.EWayland, socketPath, acl.Read|acl.Write|acl.Execute)
}
return nil
}
diff --git a/internal/outcome/spwayland_test.go b/internal/outcome/spwayland_test.go
index 7cc4ba84..9bb35512 100644
--- a/internal/outcome/spwayland_test.go
+++ b/internal/outcome/spwayland_test.go
@@ -69,7 +69,7 @@ func TestSpWaylandOp(t *testing.T) {
Ensure(m(wantRunDirPath), 0700).
UpdatePermType(system.User, m(wantRunDirPath), acl.Execute).
// toSystem
- UpdatePermType(hst.EWayland, m("/proc/nonexistent/wayland"), acl.Read, acl.Write, acl.Execute), nil, nil, insertsOps(afterSpRuntimeOp(nil)), []stub.Call{
+ UpdatePermType(hst.EWayland, m("/proc/nonexistent/wayland"), acl.Read|acl.Write|acl.Execute), nil, nil, insertsOps(afterSpRuntimeOp(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/outcome/spx11.go b/internal/outcome/spx11.go
index c71ff530..ebd5c77e 100644
--- a/internal/outcome/spx11.go
+++ b/internal/outcome/spx11.go
@@ -56,7 +56,7 @@ func (s *spX11Op) toSystem(state *outcomeStateSys) error {
), Err: err}
}
} else {
- state.sys.UpdatePermType(hst.EX11, socketPath, acl.Read, acl.Write, acl.Execute)
+ state.sys.UpdatePermType(hst.EX11, socketPath, acl.Read|acl.Write|acl.Execute)
if state.Container.Flags&hst.FHostAbstract == 0 {
s.Display = "unix:" + socketPath.String()
}
diff --git a/internal/outcome/spx11_test.go b/internal/outcome/spx11_test.go
index 0ede2d65..d183f798 100644
--- a/internal/outcome/spx11_test.go
+++ b/internal/outcome/spx11_test.go
@@ -83,7 +83,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), nil),
}, 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("#10009"), nil, nil, insertsOps(nil), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
@@ -106,7 +106,7 @@ func TestSpX11Op(t *testing.T) {
call("lookupEnv", stub.ExpectArgs{"DISPLAY"}, ":0", nil),
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).
+ UpdatePermType(hst.EX11, m("/tmp/.X11-unix/X0"), acl.Read|acl.Write|acl.Execute).
ChangeHosts("#10009"), nil, nil, insertsOps(nil), []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
diff --git a/internal/system/acl.go b/internal/system/acl.go
index e91f4eb7..7d34fa62 100644
--- a/internal/system/acl.go
+++ b/internal/system/acl.go
@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"os"
- "slices"
"hakurei.app/check"
"hakurei.app/hst"
@@ -12,14 +11,14 @@ import (
)
// UpdatePerm calls UpdatePermType with the [Process] criteria.
-func (sys *I) UpdatePerm(path *check.Absolute, perms ...acl.Perm) *I {
- sys.UpdatePermType(Process, path, perms...)
+func (sys *I) UpdatePerm(path *check.Absolute, perms acl.Perm) *I {
+ sys.UpdatePermType(Process, path, perms)
return sys
}
// UpdatePermType maintains [acl.Perms] on a file until its [hst.Enablements] is
// no longer satisfied.
-func (sys *I) UpdatePermType(et hst.Enablements, path *check.Absolute, perms ...acl.Perm) *I {
+func (sys *I) UpdatePermType(et hst.Enablements, path *check.Absolute, perms acl.Perm) *I {
sys.ops = append(sys.ops, &aclUpdateOp{et, path.String(), perms})
return sys
}
@@ -28,20 +27,20 @@ func (sys *I) UpdatePermType(et hst.Enablements, path *check.Absolute, perms ...
type aclUpdateOp struct {
et hst.Enablements
path string
- perms acl.Perms
+ perms acl.Perm
}
func (a *aclUpdateOp) Type() hst.Enablements { return a.et }
func (a *aclUpdateOp) apply(sys *I) error {
sys.msg.Verbose("applying ACL", a)
- return newOpError("acl", sys.aclUpdate(a.path, sys.uid, a.perms...), false)
+ return newOpError("acl", sys.aclUpdate(a.path, sys.uid, a.perms), false)
}
func (a *aclUpdateOp) revert(sys *I, ec *Criteria) error {
if ec.hasType(a.Type()) {
sys.msg.Verbose("stripping ACL", a)
- err := sys.aclUpdate(a.path, sys.uid)
+ err := sys.aclUpdate(a.path, sys.uid, 0)
if errors.Is(err, os.ErrNotExist) {
// the ACL is effectively stripped if the file no longer exists
sys.msg.Verbosef("target of ACL %s no longer exists", a)
@@ -57,9 +56,7 @@ func (a *aclUpdateOp) revert(sys *I, ec *Criteria) error {
func (a *aclUpdateOp) Is(o Op) bool {
target, ok := o.(*aclUpdateOp)
return ok && a != nil && target != nil &&
- a.et == target.et &&
- a.path == target.path &&
- slices.Equal(a.perms, target.perms)
+ *a == *target
}
func (a *aclUpdateOp) Path() string { return a.path }
diff --git a/internal/system/acl_test.go b/internal/system/acl_test.go
index 01f9d9b1..a340e234 100644
--- a/internal/system/acl_test.go
+++ b/internal/system/acl_test.go
@@ -15,45 +15,45 @@ func TestACLUpdateOp(t *testing.T) {
checkOpBehaviour(t, 0, []opBehaviourTestCase{
{"apply aclUpdate", 0xbeef, 0xff,
- &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, stub.UniqueError(1)),
+ &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}, []stub.Call{
+ call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, stub.UniqueError(1)),
}, &OpError{Op: "acl", Err: stub.UniqueError(1)}, nil, nil},
{"revert aclUpdate", 0xbeef, 0xff,
- &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}, []stub.Call{
+ call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, ([]acl.Perm)(nil)}, nil, stub.UniqueError(0)),
+ call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Perm(0)}, nil, stub.UniqueError(0)),
}, &OpError{Op: "acl", Err: stub.UniqueError(0), Revert: true}},
{"success revert skip", 0xbeef, Process,
- &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ &aclUpdateOp{User, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}, []stub.Call{
+ call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{User, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"skipping ACL", &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
+ call("verbose", stub.ExpectArgs{[]any{"skipping ACL", &aclUpdateOp{User, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
}, nil},
{"success revert aclUpdate ENOENT", 0xbeef, 0xff,
- &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}, []stub.Call{
+ call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, ([]acl.Perm)(nil)}, nil, &os.PathError{Op: "acl_get_file", Path: "/proc/nonexistent", Err: syscall.ENOENT}),
- call("verbosef", stub.ExpectArgs{"target of ACL %s no longer exists", []any{&aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
+ call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Perm(0)}, nil, &os.PathError{Op: "acl_get_file", Path: "/proc/nonexistent", Err: syscall.ENOENT}),
+ call("verbosef", stub.ExpectArgs{"target of ACL %s no longer exists", []any{&aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
}, nil},
{"success", 0xbeef, 0xff,
- &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}, []stub.Call{
+ call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
- call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, ([]acl.Perm)(nil)}, nil, nil),
+ call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", acl.Read | acl.Write | acl.Execute}}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xbeef, acl.Perm(0)}, nil, nil),
}, nil},
})
@@ -63,28 +63,28 @@ func TestACLUpdateOp(t *testing.T) {
func(_ *testing.T, sys *I) {
sys.
UpdatePerm(m("/run/user/1971/hakurei"), acl.Execute).
- UpdatePerm(m("/tmp/hakurei.0/tmpdir/150"), acl.Read, acl.Write, acl.Execute)
+ UpdatePerm(m("/tmp/hakurei.0/tmpdir/150"), acl.Read|acl.Write|acl.Execute)
}, []Op{
- &aclUpdateOp{Process, "/run/user/1971/hakurei", []acl.Perm{acl.Execute}},
- &aclUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
+ &aclUpdateOp{Process, "/run/user/1971/hakurei", acl.Execute},
+ &aclUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", acl.Read | acl.Write | acl.Execute},
}, stub.Expect{}},
{"tmpdirp", 0xbeef, func(_ *testing.T, sys *I) {
sys.UpdatePermType(User, m("/tmp/hakurei.0/tmpdir"), acl.Execute)
}, []Op{
- &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir", []acl.Perm{acl.Execute}},
+ &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir", acl.Execute},
}, stub.Expect{}},
{"tmpdir", 0xbeef, func(_ *testing.T, sys *I) {
- sys.UpdatePermType(User, m("/tmp/hakurei.0/tmpdir/150"), acl.Read, acl.Write, acl.Execute)
+ sys.UpdatePermType(User, m("/tmp/hakurei.0/tmpdir/150"), acl.Read|acl.Write|acl.Execute)
}, []Op{
- &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
+ &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", acl.Read | acl.Write | acl.Execute},
}, stub.Expect{}},
{"share", 0xbeef, func(_ *testing.T, sys *I) {
sys.UpdatePermType(Process, m("/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5"), acl.Execute)
}, []Op{
- &aclUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", []acl.Perm{acl.Execute}},
+ &aclUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", acl.Execute},
}, stub.Expect{}},
{"passwd", 0xbeef, func(_ *testing.T, sys *I) {
@@ -92,14 +92,14 @@ func TestACLUpdateOp(t *testing.T) {
UpdatePermType(Process, m("/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd"), acl.Read).
UpdatePermType(Process, m("/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group"), acl.Read)
}, []Op{
- &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", []acl.Perm{acl.Read}},
- &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", []acl.Perm{acl.Read}},
+ &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", acl.Read},
+ &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", acl.Read},
}, stub.Expect{}},
{"wayland", 0xbeef, func(_ *testing.T, sys *I) {
- sys.UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read, acl.Write, acl.Execute)
+ sys.UpdatePermType(hst.EWayland, m("/run/user/1971/wayland-0"), acl.Read|acl.Write|acl.Execute)
}, []Op{
- &aclUpdateOp{hst.EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
+ &aclUpdateOp{hst.EWayland, "/run/user/1971/wayland-0", acl.Read | acl.Write | acl.Execute},
}, stub.Expect{}},
})
@@ -110,75 +110,75 @@ func TestACLUpdateOp(t *testing.T) {
{"et differs",
&aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, &aclUpdateOp{
hst.EX11, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, false},
{"path differs", &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-1",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, false},
{"perms differs", &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write},
+ acl.Read | acl.Write,
}, false},
{"equals", &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, &aclUpdateOp{
hst.EWayland, "/run/user/1971/wayland-0",
- []acl.Perm{acl.Read, acl.Write, acl.Execute},
+ acl.Read | acl.Write | acl.Execute,
}, true},
})
checkOpMeta(t, []opMetaTestCase{
{"clear",
- &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{}},
+ &aclUpdateOp{Process, "/proc/nonexistent", 0},
Process, "/proc/nonexistent",
`--- type: process path: "/proc/nonexistent"`},
{"read",
- &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0", []acl.Perm{acl.Read}},
+ &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0", acl.Read},
User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0",
`r-- type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0"`},
{"write",
- &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1", []acl.Perm{acl.Write}},
+ &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1", acl.Write},
User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1",
`-w- type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1"`},
{"execute",
- &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2", []acl.Perm{acl.Execute}},
+ &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2", acl.Execute},
User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2",
`--x type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2"`},
{"wayland",
- &aclUpdateOp{hst.EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland", []acl.Perm{acl.Read, acl.Write}},
+ &aclUpdateOp{hst.EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland", acl.Read | acl.Write},
hst.EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland",
`rw- type: wayland path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland"`},
{"x11",
- &aclUpdateOp{hst.EX11, "/tmp/.X11-unix/X0", []acl.Perm{acl.Read, acl.Execute}},
+ &aclUpdateOp{hst.EX11, "/tmp/.X11-unix/X0", acl.Read | acl.Execute},
hst.EX11, "/tmp/.X11-unix/X0",
`r-x type: x11 path: "/tmp/.X11-unix/X0"`},
{"dbus",
- &aclUpdateOp{hst.EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus", []acl.Perm{acl.Write, acl.Execute}},
+ &aclUpdateOp{hst.EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus", acl.Write | acl.Execute},
hst.EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus",
`-wx type: dbus path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus"`},
{"pulseaudio",
- &aclUpdateOp{hst.EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse", []acl.Perm{acl.Read, acl.Write, acl.Execute}},
+ &aclUpdateOp{hst.EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse", acl.Read | acl.Write | acl.Execute},
hst.EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse",
`rwx type: pulseaudio path: "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse"`},
})
diff --git a/internal/system/dispatcher.go b/internal/system/dispatcher.go
index 8f70b0c0..5a222176 100644
--- a/internal/system/dispatcher.go
+++ b/internal/system/dispatcher.go
@@ -50,7 +50,7 @@ type syscallDispatcher interface {
println(v ...any)
// aclUpdate provides [acl.Update].
- aclUpdate(name string, uid int, perms ...acl.Perm) error
+ aclUpdate(name string, uid int, perms acl.Perm) error
// waylandNew provides [wayland.New].
waylandNew(displayPath, bindPath *check.Absolute, appID, instanceID string) (io.Closer, error)
@@ -85,8 +85,8 @@ func (k direct) remove(name string) error { return os.Remove(na
func (k direct) println(v ...any) { log.Println(v...) }
-func (k direct) aclUpdate(name string, uid int, perms ...acl.Perm) error {
- return acl.Update(name, uid, perms...)
+func (k direct) aclUpdate(name string, uid int, perms acl.Perm) error {
+ return acl.Update(name, uid, perms)
}
func (k direct) waylandNew(displayPath, bindPath *check.Absolute, appID, instanceID string) (io.Closer, error) {
diff --git a/internal/system/dispatcher_test.go b/internal/system/dispatcher_test.go
index 3bf14e75..6ffd0dfa 100644
--- a/internal/system/dispatcher_test.go
+++ b/internal/system/dispatcher_test.go
@@ -280,7 +280,7 @@ func (k *kstub) println(v ...any) {
}
}
-func (k *kstub) aclUpdate(name string, uid int, perms ...acl.Perm) error {
+func (k *kstub) aclUpdate(name string, uid int, perms acl.Perm) error {
k.Helper()
expect := k.Expects("aclUpdate")
@@ -293,7 +293,7 @@ func (k *kstub) aclUpdate(name string, uid int, perms ...acl.Perm) error {
return expect.Error(
stub.CheckArgReflect(k.Stub, "name", nameVal, 0),
stub.CheckArg(k.Stub, "uid", uid, 1),
- stub.CheckArgReflect(k.Stub, "perms", perms, 2))
+ stub.CheckArg(k.Stub, "perms", perms, 2))
}
func (k *kstub) waylandNew(displayPath, bindPath *check.Absolute, appID, instanceID string) (io.Closer, error) {
diff --git a/internal/system/pipewire.go b/internal/system/pipewire.go
index c2d7b396..427013a4 100644
--- a/internal/system/pipewire.go
+++ b/internal/system/pipewire.go
@@ -73,7 +73,7 @@ func (p *pipewireOp) apply(sys *I) (err error) {
return newOpError("pipewire", err, false)
}
- if err = sys.aclUpdate(p.dst.String(), sys.uid, acl.Read, acl.Write, acl.Execute); err != nil {
+ if err = sys.aclUpdate(p.dst.String(), sys.uid, acl.Read|acl.Write|acl.Execute); err != nil {
if closeErr := p.scc.Close(); closeErr != nil {
return newOpError("pipewire", errors.Join(err, closeErr), false)
}
diff --git a/internal/system/pipewire_test.go b/internal/system/pipewire_test.go
index f0ca0b34..5953681e 100644
--- a/internal/system/pipewire_test.go
+++ b/internal/system/pipewire_test.go
@@ -423,7 +423,7 @@ func TestPipeWireOp(t *testing.T) {
call("verbosef", stub.ExpectArgs{"pipewire pathname socket on %q", []any{ignoreValue{}}}, nil, nil),
call("chmod", stub.ExpectArgs{ignoreValue{}, os.FileMode(0)}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{ignoreValue{}, 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{ignoreValue{}, 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
call("verbosef", stub.ExpectArgs{"hanging up pipewire socket on %q", []any{ignoreValue{}}}, nil, nil),
}, nil},
diff --git a/internal/system/wayland.go b/internal/system/wayland.go
index c22c3fdf..e86c3159 100644
--- a/internal/system/wayland.go
+++ b/internal/system/wayland.go
@@ -42,7 +42,7 @@ func (w *waylandOp) apply(sys *I) (err error) {
return newOpError("wayland", err, false)
}
- if err = sys.aclUpdate(w.dst.String(), sys.uid, acl.Read, acl.Write, acl.Execute); err != nil {
+ if err = sys.aclUpdate(w.dst.String(), sys.uid, acl.Read|acl.Write|acl.Execute); err != nil {
if closeErr := w.ctx.Close(); closeErr != nil {
return newOpError("wayland", errors.Join(err, closeErr), false)
}
diff --git a/internal/system/wayland_test.go b/internal/system/wayland_test.go
index 76e6cc93..a9d29378 100644
--- a/internal/system/wayland_test.go
+++ b/internal/system/wayland_test.go
@@ -32,7 +32,7 @@ func TestWaylandOp(t *testing.T) {
call("waylandNew", stub.ExpectArgs{m("/run/user/1971/wayland-0"), m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c"}, nil, nil),
call("verbosef", stub.ExpectArgs{"wayland pathname socket on %q via %q", []any{m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0")}}, nil, nil),
call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, stub.UniqueError(2)),
+ call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, stub.UniqueError(2)),
}, &OpError{Op: "wayland", Err: stub.UniqueError(2)}, nil, nil},
{"success", 0xbeef, 0xff, &waylandOp{nil,
@@ -44,7 +44,7 @@ func TestWaylandOp(t *testing.T) {
call("waylandNew", stub.ExpectArgs{m("/run/user/1971/wayland-0"), m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"), "org.chromium.Chromium", "ebf083d1b175911782d413369b64ce7c"}, nil, nil),
call("verbosef", stub.ExpectArgs{"wayland pathname socket on %q via %q", []any{m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/1971/wayland-0")}}, nil, nil),
call("chmod", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", os.FileMode(0)}, nil, nil),
- call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil),
+ call("aclUpdate", stub.ExpectArgs{"/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", 0xbeef, acl.Read | acl.Write | acl.Execute}, nil, nil),
}, nil, []stub.Call{
call("verbosef", stub.ExpectArgs{"hanging up wayland socket on %q", []any{m("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland")}}, nil, nil),
}, nil},