Compare commits

..

1 Commits

Author SHA1 Message Date
a5baad9e00
container: optionally isolate host abstract UNIX domain sockets via landlock
Some checks failed
Test / Create distribution (push) Failing after 29s
Test / Sandbox (push) Successful in 2m15s
Test / Sandbox (pull_request) Successful in 1m25s
Test / Hpkg (push) Successful in 4m21s
Test / Hpkg (pull_request) Successful in 2m5s
Test / Sandbox (race detector) (push) Successful in 4m27s
Test / Sandbox (race detector) (pull_request) Successful in 2m14s
Test / Create distribution (pull_request) Failing after 27s
Test / Hakurei (push) Failing after 20m53s
Test / Hakurei (race detector) (pull_request) Failing after 22m5s
Test / Hakurei (pull_request) Failing after 39m56s
Test / Flake checks (pull_request) Has been skipped
Test / Hakurei (race detector) (push) Failing after 42m26s
Test / Flake checks (push) Has been skipped
2025-08-18 02:36:42 +09:00
6 changed files with 41 additions and 16 deletions

View File

@ -7,7 +7,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
@ -15,7 +14,6 @@ import (
. "syscall" . "syscall"
"time" "time"
"hakurei.app/container/landlock"
"hakurei.app/container/seccomp" "hakurei.app/container/seccomp"
) )
@ -183,12 +181,6 @@ func (p *Container) Start() error {
p.wait = make(chan struct{}) p.wait = make(chan struct{})
done <- func() error { // setup depending on per-thread state must happen here done <- func() error { // setup depending on per-thread state must happen here
if p.ScopeAbstract {
if err := landlock.ScopeAbstract(); err != nil {
log.Fatalf("could not scope abstract unix sockets: %v", err)
}
}
msg.Verbose("starting container init") msg.Verbose("starting container init")
if err := p.cmd.Start(); err != nil { if err := p.cmd.Start(); err != nil {
return msg.WrapErr(err, err.Error()) return msg.WrapErr(err, err.Error())

View File

@ -13,6 +13,7 @@ import (
. "syscall" . "syscall"
"time" "time"
"hakurei.app/container/landlock"
"hakurei.app/container/seccomp" "hakurei.app/container/seccomp"
) )
@ -263,6 +264,12 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
msg.Verbose("syscall filter not configured") msg.Verbose("syscall filter not configured")
} }
if params.ScopeAbstract {
if err := landlock.ScopeAbstract(); err != nil {
log.Fatalf("could not scope abstract unix sockets: %v", err)
}
}
extraFiles := make([]*os.File, params.Count) extraFiles := make([]*os.File, params.Count)
for i := range extraFiles { for i := range extraFiles {
// setup fd is placed before all extra files // setup fd is placed before all extra files

View File

@ -0,0 +1,14 @@
#include <errno.h>
#include <linux/landlock.h>
#include <sys/psx_syscall.h>
#include <sys/syscall.h>
#include "landlock-helper.h"
int hakurei_scope_abstract_unix_sockets(int* p_errno, int fd) {
int res = psx_syscall3(SYS_landlock_restrict_self, fd, 0, 0);
*p_errno = errno;
return res;
}

View File

@ -0,0 +1,3 @@
#pragma once
int hakurei_scope_abstract_unix_sockets(int* p_errno, int fd);

View File

@ -1,8 +1,12 @@
package landlock package landlock
/* /*
#cgo linux pkg-config: --static libpsx
#include <linux/landlock.h> #include <linux/landlock.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include "landlock-helper.h"
*/ */
import "C" import "C"
@ -17,13 +21,10 @@ const (
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = C.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = C.LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
SYS_LANDLOCK_CREATE_RULESET = C.SYS_landlock_create_ruleset SYS_LANDLOCK_CREATE_RULESET = C.SYS_landlock_create_ruleset
SYS_LANDLOCK_RESTRICT_SELF = C.SYS_landlock_restrict_self
) )
type LandlockRulesetAttr = C.struct_landlock_ruleset_attr type LandlockRulesetAttr = C.struct_landlock_ruleset_attr
// ScopeAbstract calls landlock_restrict_self and must be called from a goroutine wired to an m
// with the process starting from the same goroutine.
func ScopeAbstract() error { func ScopeAbstract() error {
abi, _, err := syscall.Syscall(SYS_LANDLOCK_CREATE_RULESET, 0, 0, LANDLOCK_CREATE_RULESET_VERSION) abi, _, err := syscall.Syscall(SYS_LANDLOCK_CREATE_RULESET, 0, 0, LANDLOCK_CREATE_RULESET_VERSION)
@ -47,9 +48,10 @@ func ScopeAbstract() error {
defer syscall.Close(int(fd)) defer syscall.Close(int(fd))
r, _, err := syscall.Syscall(SYS_LANDLOCK_RESTRICT_SELF, fd, 0, 0) var errno C.int
if r != 0 { if rv := C.hakurei_scope_abstract_unix_sockets(&errno, C.int(fd)); rv != 0 {
return fmt.Errorf("could not restrict self via landlock: errno %v", err) return fmt.Errorf("could not restrict self via landlock: errno %v", errno)
} }
return nil return nil
} }

View File

@ -5,6 +5,7 @@
makeBinaryWrapper, makeBinaryWrapper,
xdg-dbus-proxy, xdg-dbus-proxy,
pkg-config, pkg-config,
libcap,
libffi, libffi,
libseccomp, libseccomp,
acl, acl,
@ -80,10 +81,16 @@ buildGoModule rec {
hsu = "/run/wrappers/bin/hsu"; hsu = "/run/wrappers/bin/hsu";
}; };
# nix build environment does not allow acls env = {
env.GO_TEST_SKIP_ACL = 1; # required by libpsx
CGO_LDFLAGS_ALLOW = "-Wl,(--no-whole-archive|--whole-archive)";
# nix build environment does not allow acls
GO_TEST_SKIP_ACL = 1;
};
buildInputs = [ buildInputs = [
libcap
libffi libffi
libseccomp libseccomp
acl acl