aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--container/container.go11
-rw-r--r--container/container_test.go3
-rw-r--r--container/landlock_test.go65
-rw-r--r--internal/landlock/landlock.go (renamed from container/landlock.go)58
-rw-r--r--internal/landlock/landlock_test.go65
-rw-r--r--internal/pkg/pkg_test.go3
6 files changed, 105 insertions, 100 deletions
diff --git a/container/container.go b/container/container.go
index aeea3dcc..a798084a 100644
--- a/container/container.go
+++ b/container/container.go
@@ -21,6 +21,7 @@ import (
"hakurei.app/container/std"
"hakurei.app/ext"
"hakurei.app/fhs"
+ "hakurei.app/internal/landlock"
"hakurei.app/message"
)
@@ -317,12 +318,14 @@ func (p *Container) Start() error {
// landlock: depends on per-thread state but acts on a process group
{
- rulesetAttr := &RulesetAttr{Scoped: LANDLOCK_SCOPE_SIGNAL}
+ rulesetAttr := &landlock.RulesetAttr{
+ Scoped: landlock.LANDLOCK_SCOPE_SIGNAL,
+ }
if !p.HostAbstract {
- rulesetAttr.Scoped |= LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
+ rulesetAttr.Scoped |= landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
}
- if abi, err := LandlockGetABI(); err != nil {
+ if abi, err := landlock.GetABI(); err != nil {
if p.HostAbstract || !p.HostNet {
// landlock can be skipped here as it restricts access
// to resources already covered by namespaces (pid, net)
@@ -351,7 +354,7 @@ func (p *Container) Start() error {
}
} else {
p.msg.Verbosef("enforcing landlock ruleset %s", rulesetAttr)
- if err = LandlockRestrictSelf(rulesetFd, 0); err != nil {
+ if err = landlock.RestrictSelf(rulesetFd, 0); err != nil {
_ = Close(rulesetFd)
return &StartError{
Fatal: true,
diff --git a/container/container_test.go b/container/container_test.go
index 092a7a37..41d39f68 100644
--- a/container/container_test.go
+++ b/container/container_test.go
@@ -26,6 +26,7 @@ import (
"hakurei.app/fhs"
"hakurei.app/hst"
"hakurei.app/internal/info"
+ "hakurei.app/internal/landlock"
"hakurei.app/internal/params"
"hakurei.app/ldd"
"hakurei.app/message"
@@ -456,7 +457,7 @@ func TestContainer(t *testing.T) {
c.RetainSession = tc.session
c.HostNet = tc.net
if info.CanDegrade {
- if _, err := container.LandlockGetABI(); err != nil {
+ if _, err := landlock.GetABI(); err != nil {
if !errors.Is(err, syscall.ENOSYS) {
t.Fatalf("LandlockGetABI: error = %v", err)
}
diff --git a/container/landlock_test.go b/container/landlock_test.go
deleted file mode 100644
index 87dc2496..00000000
--- a/container/landlock_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package container_test
-
-import (
- "testing"
- "unsafe"
-
- "hakurei.app/container"
-)
-
-func TestLandlockString(t *testing.T) {
- t.Parallel()
-
- testCases := []struct {
- name string
- rulesetAttr *container.RulesetAttr
- want string
- }{
- {"nil", nil, "NULL"},
- {"zero", new(container.RulesetAttr), "0"},
- {"some", &container.RulesetAttr{Scoped: container.LANDLOCK_SCOPE_SIGNAL}, "scoped: signal"},
- {"set", &container.RulesetAttr{
- HandledAccessFS: container.LANDLOCK_ACCESS_FS_MAKE_SYM | container.LANDLOCK_ACCESS_FS_IOCTL_DEV | container.LANDLOCK_ACCESS_FS_WRITE_FILE,
- HandledAccessNet: container.LANDLOCK_ACCESS_NET_BIND_TCP,
- Scoped: container.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | container.LANDLOCK_SCOPE_SIGNAL,
- }, "fs: write_file make_sym fs_ioctl_dev, net: bind_tcp, scoped: abstract_unix_socket signal"},
- {"all", &container.RulesetAttr{
- HandledAccessFS: container.LANDLOCK_ACCESS_FS_EXECUTE |
- container.LANDLOCK_ACCESS_FS_WRITE_FILE |
- container.LANDLOCK_ACCESS_FS_READ_FILE |
- container.LANDLOCK_ACCESS_FS_READ_DIR |
- container.LANDLOCK_ACCESS_FS_REMOVE_DIR |
- container.LANDLOCK_ACCESS_FS_REMOVE_FILE |
- container.LANDLOCK_ACCESS_FS_MAKE_CHAR |
- container.LANDLOCK_ACCESS_FS_MAKE_DIR |
- container.LANDLOCK_ACCESS_FS_MAKE_REG |
- container.LANDLOCK_ACCESS_FS_MAKE_SOCK |
- container.LANDLOCK_ACCESS_FS_MAKE_FIFO |
- container.LANDLOCK_ACCESS_FS_MAKE_BLOCK |
- container.LANDLOCK_ACCESS_FS_MAKE_SYM |
- container.LANDLOCK_ACCESS_FS_REFER |
- container.LANDLOCK_ACCESS_FS_TRUNCATE |
- container.LANDLOCK_ACCESS_FS_IOCTL_DEV,
- HandledAccessNet: container.LANDLOCK_ACCESS_NET_BIND_TCP |
- container.LANDLOCK_ACCESS_NET_CONNECT_TCP,
- Scoped: container.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
- container.LANDLOCK_SCOPE_SIGNAL,
- }, "fs: execute write_file read_file read_dir remove_dir remove_file make_char make_dir make_reg make_sock make_fifo make_block make_sym fs_refer fs_truncate fs_ioctl_dev, net: bind_tcp connect_tcp, scoped: abstract_unix_socket signal"},
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- if got := tc.rulesetAttr.String(); got != tc.want {
- t.Errorf("String: %s, want %s", got, tc.want)
- }
- })
- }
-}
-
-func TestLandlockAttrSize(t *testing.T) {
- t.Parallel()
- want := 24
- if got := unsafe.Sizeof(container.RulesetAttr{}); got != uintptr(want) {
- t.Errorf("Sizeof: %d, want %d", got, want)
- }
-}
diff --git a/container/landlock.go b/internal/landlock/landlock.go
index a8007692..b65e3ebe 100644
--- a/container/landlock.go
+++ b/internal/landlock/landlock.go
@@ -1,4 +1,4 @@
-package container
+package landlock
import (
"strings"
@@ -14,11 +14,11 @@ const (
LANDLOCK_CREATE_RULESET_VERSION = 1 << iota
)
-// LandlockAccessFS is bitmask of handled filesystem actions.
-type LandlockAccessFS uint64
+// AccessFS is bitmask of handled filesystem actions.
+type AccessFS uint64
const (
- LANDLOCK_ACCESS_FS_EXECUTE LandlockAccessFS = 1 << iota
+ LANDLOCK_ACCESS_FS_EXECUTE AccessFS = 1 << iota
LANDLOCK_ACCESS_FS_WRITE_FILE
LANDLOCK_ACCESS_FS_READ_FILE
LANDLOCK_ACCESS_FS_READ_DIR
@@ -38,8 +38,8 @@ const (
_LANDLOCK_ACCESS_FS_DELIM
)
-// String returns a space-separated string of [LandlockAccessFS] flags.
-func (f LandlockAccessFS) String() string {
+// String returns a space-separated string of [AccessFS] flags.
+func (f AccessFS) String() string {
switch f {
case LANDLOCK_ACCESS_FS_EXECUTE:
return "execute"
@@ -90,8 +90,8 @@ func (f LandlockAccessFS) String() string {
return "fs_ioctl_dev"
default:
- var c []LandlockAccessFS
- for i := LandlockAccessFS(1); i < _LANDLOCK_ACCESS_FS_DELIM; i <<= 1 {
+ var c []AccessFS
+ for i := AccessFS(1); i < _LANDLOCK_ACCESS_FS_DELIM; i <<= 1 {
if f&i != 0 {
c = append(c, i)
}
@@ -107,18 +107,18 @@ func (f LandlockAccessFS) String() string {
}
}
-// LandlockAccessNet is bitmask of handled network actions.
-type LandlockAccessNet uint64
+// AccessNet is bitmask of handled network actions.
+type AccessNet uint64
const (
- LANDLOCK_ACCESS_NET_BIND_TCP LandlockAccessNet = 1 << iota
+ LANDLOCK_ACCESS_NET_BIND_TCP AccessNet = 1 << iota
LANDLOCK_ACCESS_NET_CONNECT_TCP
_LANDLOCK_ACCESS_NET_DELIM
)
-// String returns a space-separated string of [LandlockAccessNet] flags.
-func (f LandlockAccessNet) String() string {
+// String returns a space-separated string of [AccessNet] flags.
+func (f AccessNet) String() string {
switch f {
case LANDLOCK_ACCESS_NET_BIND_TCP:
return "bind_tcp"
@@ -127,8 +127,8 @@ func (f LandlockAccessNet) String() string {
return "connect_tcp"
default:
- var c []LandlockAccessNet
- for i := LandlockAccessNet(1); i < _LANDLOCK_ACCESS_NET_DELIM; i <<= 1 {
+ var c []AccessNet
+ for i := AccessNet(1); i < _LANDLOCK_ACCESS_NET_DELIM; i <<= 1 {
if f&i != 0 {
c = append(c, i)
}
@@ -144,18 +144,18 @@ func (f LandlockAccessNet) String() string {
}
}
-// LandlockScope is bitmask of scopes restricting a Landlock domain from accessing outside resources.
-type LandlockScope uint64
+// Scope is bitmask of scopes restricting a Landlock domain from accessing outside resources.
+type Scope uint64
const (
- LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET LandlockScope = 1 << iota
+ LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET Scope = 1 << iota
LANDLOCK_SCOPE_SIGNAL
_LANDLOCK_SCOPE_DELIM
)
-// String returns a space-separated string of [LandlockScope] flags.
-func (f LandlockScope) String() string {
+// String returns a space-separated string of [Scope] flags.
+func (f Scope) String() string {
switch f {
case LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET:
return "abstract_unix_socket"
@@ -164,8 +164,8 @@ func (f LandlockScope) String() string {
return "signal"
default:
- var c []LandlockScope
- for i := LandlockScope(1); i < _LANDLOCK_SCOPE_DELIM; i <<= 1 {
+ var c []Scope
+ for i := Scope(1); i < _LANDLOCK_SCOPE_DELIM; i <<= 1 {
if f&i != 0 {
c = append(c, i)
}
@@ -184,12 +184,12 @@ func (f LandlockScope) String() string {
// RulesetAttr is equivalent to struct landlock_ruleset_attr.
type RulesetAttr struct {
// Bitmask of handled filesystem actions.
- HandledAccessFS LandlockAccessFS
+ HandledAccessFS AccessFS
// Bitmask of handled network actions.
- HandledAccessNet LandlockAccessNet
+ HandledAccessNet AccessNet
// Bitmask of scopes restricting a Landlock domain from accessing outside
// resources (e.g. IPCs).
- Scoped LandlockScope
+ Scoped Scope
}
// String returns a user-facing description of [RulesetAttr].
@@ -239,13 +239,13 @@ func (rulesetAttr *RulesetAttr) Create(flags uintptr) (fd int, err error) {
return fd, nil
}
-// LandlockGetABI returns the ABI version supported by the kernel.
-func LandlockGetABI() (int, error) {
+// GetABI returns the ABI version supported by the kernel.
+func GetABI() (int, error) {
return (*RulesetAttr)(nil).Create(LANDLOCK_CREATE_RULESET_VERSION)
}
-// LandlockRestrictSelf applies a loaded ruleset to the calling thread.
-func LandlockRestrictSelf(rulesetFd int, flags uintptr) error {
+// RestrictSelf applies a loaded ruleset to the calling thread.
+func RestrictSelf(rulesetFd int, flags uintptr) error {
r, _, errno := syscall.Syscall(
ext.SYS_LANDLOCK_RESTRICT_SELF,
uintptr(rulesetFd),
diff --git a/internal/landlock/landlock_test.go b/internal/landlock/landlock_test.go
new file mode 100644
index 00000000..6f30fc6b
--- /dev/null
+++ b/internal/landlock/landlock_test.go
@@ -0,0 +1,65 @@
+package landlock_test
+
+import (
+ "testing"
+ "unsafe"
+
+ "hakurei.app/internal/landlock"
+)
+
+func TestLandlockString(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ rulesetAttr *landlock.RulesetAttr
+ want string
+ }{
+ {"nil", nil, "NULL"},
+ {"zero", new(landlock.RulesetAttr), "0"},
+ {"some", &landlock.RulesetAttr{Scoped: landlock.LANDLOCK_SCOPE_SIGNAL}, "scoped: signal"},
+ {"set", &landlock.RulesetAttr{
+ HandledAccessFS: landlock.LANDLOCK_ACCESS_FS_MAKE_SYM | landlock.LANDLOCK_ACCESS_FS_IOCTL_DEV | landlock.LANDLOCK_ACCESS_FS_WRITE_FILE,
+ HandledAccessNet: landlock.LANDLOCK_ACCESS_NET_BIND_TCP,
+ Scoped: landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | landlock.LANDLOCK_SCOPE_SIGNAL,
+ }, "fs: write_file make_sym fs_ioctl_dev, net: bind_tcp, scoped: abstract_unix_socket signal"},
+ {"all", &landlock.RulesetAttr{
+ HandledAccessFS: landlock.LANDLOCK_ACCESS_FS_EXECUTE |
+ landlock.LANDLOCK_ACCESS_FS_WRITE_FILE |
+ landlock.LANDLOCK_ACCESS_FS_READ_FILE |
+ landlock.LANDLOCK_ACCESS_FS_READ_DIR |
+ landlock.LANDLOCK_ACCESS_FS_REMOVE_DIR |
+ landlock.LANDLOCK_ACCESS_FS_REMOVE_FILE |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_CHAR |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_DIR |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_REG |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_SOCK |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_FIFO |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_BLOCK |
+ landlock.LANDLOCK_ACCESS_FS_MAKE_SYM |
+ landlock.LANDLOCK_ACCESS_FS_REFER |
+ landlock.LANDLOCK_ACCESS_FS_TRUNCATE |
+ landlock.LANDLOCK_ACCESS_FS_IOCTL_DEV,
+ HandledAccessNet: landlock.LANDLOCK_ACCESS_NET_BIND_TCP |
+ landlock.LANDLOCK_ACCESS_NET_CONNECT_TCP,
+ Scoped: landlock.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
+ landlock.LANDLOCK_SCOPE_SIGNAL,
+ }, "fs: execute write_file read_file read_dir remove_dir remove_file make_char make_dir make_reg make_sock make_fifo make_block make_sym fs_refer fs_truncate fs_ioctl_dev, net: bind_tcp connect_tcp, scoped: abstract_unix_socket signal"},
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ if got := tc.rulesetAttr.String(); got != tc.want {
+ t.Errorf("String: %s, want %s", got, tc.want)
+ }
+ })
+ }
+}
+
+func TestLandlockAttrSize(t *testing.T) {
+ t.Parallel()
+ want := 24
+ if got := unsafe.Sizeof(landlock.RulesetAttr{}); got != uintptr(want) {
+ t.Errorf("Sizeof: %d, want %d", got, want)
+ }
+}
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
index e1deaf3d..b2a5dfbc 100644
--- a/internal/pkg/pkg_test.go
+++ b/internal/pkg/pkg_test.go
@@ -25,6 +25,7 @@ import (
"hakurei.app/container"
"hakurei.app/fhs"
"hakurei.app/internal/info"
+ "hakurei.app/internal/landlock"
"hakurei.app/internal/pkg"
"hakurei.app/internal/stub"
"hakurei.app/message"
@@ -293,7 +294,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
flags := tc.flags
if info.CanDegrade {
- if _, err := container.LandlockGetABI(); err != nil {
+ if _, err := landlock.GetABI(); err != nil {
if !errors.Is(err, syscall.ENOSYS) {
t.Fatalf("LandlockGetABI: error = %v", err)
}