diff options
Diffstat (limited to 'test')
39 files changed, 0 insertions, 6552 deletions
diff --git a/test/configuration.nix b/test/configuration.nix deleted file mode 100644 index 62d8239d..00000000 --- a/test/configuration.nix +++ /dev/null @@ -1,252 +0,0 @@ -{ - lib, - pkgs, - config, - ... -}: -{ - users.users = { - alice = { - isNormalUser = true; - description = "Alice Foobar"; - password = "foobar"; - uid = 1000; - }; - untrusted = { - isNormalUser = true; - description = "Untrusted user"; - password = "foobar"; - uid = 1001; - - # For deny unmapped uid test: - packages = [ config.environment.hakurei.package ]; - }; - }; - - home-manager.users.alice.home.stateVersion = "24.11"; - - # Automatically login on tty1 as a normal user: - services.getty.autologinUser = "alice"; - - security.pam.loginLimits = [ - { - domain = "@users"; - item = "rtprio"; - type = "-"; - value = 1; - } - ]; - - environment = { - systemPackages = with pkgs; [ - # For D-Bus tests: - mako - libnotify - ]; - - variables = { - SWAYSOCK = "/tmp/sway-ipc.sock"; - WLR_RENDERER = "pixman"; - }; - - # To help with OCR: - etc."xdg/foot/foot.ini".text = lib.generators.toINI { } { - main = { - font = "inconsolata:size=14"; - }; - colors = rec { - foreground = "000000"; - background = "ffffff"; - regular2 = foreground; - }; - }; - }; - - fonts.packages = [ pkgs.inconsolata ]; - - # Automatically configure and start Sway when logging in on tty1: - programs.bash.loginShellInit = '' - if [ "$(tty)" = "/dev/tty1" ]; then - set -e - - mkdir -p ~/.config/sway - (sed s/Mod4/Mod1/ /etc/sway/config && - echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill' && - echo 'output Virtual-1 res 1680x1050') > ~/.config/sway/config - - sway --validate - systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok - fi - ''; - - programs.sway.enable = true; - - # For PulseAudio tests: - security.rtkit.enable = true; - services.pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - }; - - virtualisation = { - # Hopefully reduces spurious test failures: - memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192; - - qemu.options = [ - # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch: - "-vga none -device virtio-gpu-pci" - - # Increase Go test compiler performance: - "-smp 16" - ]; - }; - - # Disk image is too small for some tests: - boot.tmp.useTmpfs = true; - - environment.hakurei = { - enable = true; - stateDir = "/var/lib/hakurei"; - users.alice = 0; - - extraHomeConfig = - { config, ... }: - { - # To test merge deduplication: - options._hakurei.stateVersion = lib.mkOption { type = lib.types.str; }; - - config = { - home = { inherit (config._hakurei) stateVersion; }; - _hakurei.stateVersion = "23.05"; - }; - }; - - commonPaths = [ - { - type = "bind"; - src = "/var/tmp"; - write = true; - } - ]; - - apps = { - "cat.gensokyo.extern.bash.linger-timeout" = { - name = "hakurei-check-linger-timeout"; - identity = 9999; - share = pkgs.bash; - packages = [ pkgs.bash ]; - command = '' - sleep infinity & disown - exit - ''; - wait_delay = 1; - enablements = { - wayland = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.foot.noEnablements" = { - name = "ne-foot"; - identity = 1; - shareUid = true; - verbose = true; - share = pkgs.foot; - packages = with pkgs; [ - foot - - # For wayland-info: - wayland-utils - ]; - command = "foot"; - enablements = { - dbus = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.foot.noEnablements.immediate" = { - name = "ne-foot-immediate"; - identity = 1; - shareUid = true; - verbose = true; - wait_delay = -1; - share = pkgs.foot; - packages = [ ]; - command = "foot"; - enablements = { - dbus = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.foot.pulseaudio" = { - name = "pa-foot"; - identity = 2; - verbose = true; - share = pkgs.foot; - packages = [ pkgs.foot ]; - command = "foot"; - enablements.dbus = false; - }; - - "cat.gensokyo.extern.Alacritty.x11" = { - name = "x11-alacritty"; - identity = 1; - shareUid = true; - verbose = true; - share = pkgs.alacritty; - packages = with pkgs; [ - # For X11 terminal emulator: - alacritty - - # For glinfo: - mesa-demos - ]; - command = "alacritty"; - enablements = { - wayland = false; - x11 = true; - dbus = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.foot.directWayland" = { - name = "da-foot"; - identity = 4; - verbose = true; - insecureWayland = true; - share = pkgs.foot; - packages = with pkgs; [ - foot - - # For wayland-info: - wayland-utils - ]; - command = "foot"; - enablements = { - dbus = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.strace.wantFail" = { - name = "strace-failure"; - identity = 5; - verbose = true; - share = pkgs.strace; - command = "strace true"; - enablements = { - wayland = false; - x11 = false; - dbus = false; - pipewire = false; - }; - }; - }; - }; -} diff --git a/test/default.nix b/test/default.nix deleted file mode 100644 index 81daa0a2..00000000 --- a/test/default.nix +++ /dev/null @@ -1,81 +0,0 @@ -{ - lib, - testers, - buildFHSEnv, - writeShellScriptBin, - - system, - self, - withRace ? false, -}: - -testers.nixosTest { - name = "hakurei" + (if withRace then "-race" else ""); - nodes.machine = - { options, pkgs, ... }: - let - fhs = - let - hakurei = options.environment.hakurei.package.default; - in - buildFHSEnv { - pname = "hakurei-fhs"; - inherit (hakurei) version; - targetPkgs = _: hakurei.targetPkgs; - extraOutputsToInstall = [ "dev" ]; - profile = '' - export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH" - ''; - }; - in - { - environment.systemPackages = [ - # For go tests: - (writeShellScriptBin "hakurei-test" '' - # Assert hst CGO_ENABLED=0: ${ - with pkgs; - runCommand "hakurei-hst-cgo" { nativeBuildInputs = [ self.packages.${system}.hakurei.go ]; } '' - cp -r ${options.environment.hakurei.package.default.src} "$out" - chmod -R +w "$out" - cp ${writeText "hst_cgo_test.go" ''package hakurei_test;import("testing";"hakurei.app/hst");func TestTemplate(t *testing.T){hst.Template()}''} "$out/hst_cgo_test.go" - (cd "$out" && HOME="$(mktemp -d)" CGO_ENABLED=0 go test .) - '' - } - - cd ${self.packages.${system}.hakurei.src} - ${fhs}/bin/hakurei-fhs -c \ - 'CC="clang -O3 -Werror" go test --tags=noskip ${if withRace then "-race" else "-count 16"} ./...' \ - &> /tmp/hakurei-test.log && \ - touch /tmp/hakurei-test-ok - touch /tmp/hakurei-test-done - '') - ]; - - # Run with Go race detector: - environment.hakurei = lib.mkIf withRace rec { - # race detector does not support static linking - package = (pkgs.callPackage ./package.nix { }).overrideAttrs (previousAttrs: { - env = previousAttrs.env // { - GOFLAGS = previousAttrs.env.GOFLAGS + " -race"; - }; - }); - hsuPackage = options.environment.hakurei.hsuPackage.default.override { hakurei = package; }; - }; - - imports = [ - ./configuration.nix - - self.nixosModules.hakurei - self.inputs.home-manager.nixosModules.home-manager - ]; - }; - - # adapted from nixos sway integration tests - - # testScriptWithTypes:49: error: Cannot call function of unknown type - # (machine.succeed if succeed else machine.execute)( - # ^ - # Found 1 error in 1 file (checked 1 source file) - skipTypeCheck = true; - testScript = builtins.readFile ./test.py; -} diff --git a/test/flake.lock b/test/flake.lock deleted file mode 100644 index 5537506a..00000000 --- a/test/flake.lock +++ /dev/null @@ -1,49 +0,0 @@ -{ - "nodes": { - "home-manager": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1787146702, - "narHash": "sha256-YbRcLdU/yK4gWsQg7V8WTKZHfXL33g8+wSFUX3wyevs=", - "owner": "nix-community", - "repo": "home-manager", - "rev": "173b7e8d40fdc8c296a9c99854314f17a3a1704c", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "release-26.05", - "repo": "home-manager", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1787101114, - "narHash": "sha256-gwrPcFf/rDjHPaVflbDZ040ZDmBTRj/7+s8ZmE2SaIM=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b18a4b905f8d028dc4476412e6d6891728695379", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-26.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "home-manager": "home-manager", - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/test/flake.nix b/test/flake.nix deleted file mode 100644 index 01a07f78..00000000 --- a/test/flake.nix +++ /dev/null @@ -1,255 +0,0 @@ -{ - description = "hakurei container tool and nixos module"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; - - home-manager = { - url = "github:nix-community/home-manager/release-26.05"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = - { - self, - nixpkgs, - home-manager, - }: - let - supportedSystems = [ - "aarch64-linux" - "i686-linux" - "x86_64-linux" - ]; - - forAllSystems = nixpkgs.lib.genAttrs supportedSystems; - nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); - in - { - nixosModules.hakurei = import ./nixos.nix self.packages; - - checks = forAllSystems ( - system: - let - pkgs = nixpkgsFor.${system}; - - inherit (pkgs) - runCommandLocal - callPackage - nixfmt - deadnix - statix - ; - in - { - hakurei = callPackage ./. { inherit system self; }; - race = callPackage ./. { - inherit system self; - withRace = true; - }; - - sandbox = callPackage ./sandbox { inherit self; }; - sandbox-race = callPackage ./sandbox { - inherit self; - withRace = true; - }; - - sharefs = callPackage ./sharefs { inherit system self; }; - - formatting = runCommandLocal "check-formatting" { nativeBuildInputs = [ nixfmt ]; } '' - cd ${./.} - - echo "running nixfmt..." - nixfmt --width=256 --check . - - touch $out - ''; - - lint = - runCommandLocal "check-lint" - { - nativeBuildInputs = [ - deadnix - statix - ]; - } - '' - cd ${./.} - - echo "running deadnix..." - deadnix --fail - - echo "running statix..." - statix check . - - touch $out - ''; - } - ); - - packages = forAllSystems ( - system: - let - inherit (self.packages.${system}) hakurei hsu; - pkgs = nixpkgsFor.${system}; - in - { - default = hakurei; - hakurei = pkgs.pkgsStatic.callPackage ./package.nix { - inherit (pkgs) - # passthru.buildInputs - go_1_27 - clang - - # nativeBuildInputs - pkg-config - wayland-scanner - makeBinaryWrapper - - # appPackages - glibc - xdg-dbus-proxy - - # for check - util-linux - nettools - ; - }; - hsu = pkgs.callPackage ./hsu.nix { inherit (self.packages.${system}) hakurei; }; - sharefs = pkgs.linkFarm "sharefs" { - "bin/sharefs" = "${hakurei}/libexec/sharefs"; - "bin/mount.fuse.sharefs" = "${hakurei}/libexec/sharefs"; - }; - - dist = - pkgs.runCommand "${hakurei.name}-dist" - { - buildInputs = hakurei.targetPkgs ++ [ - pkgs.pkgsStatic.musl - ]; - } - '' - cd $(mktemp -d) \ - && cp -r ${hakurei.src}/. . \ - && chmod +w cmd && cp -r ${hsu.src}/. cmd/hsu/ \ - && chmod -R +w . - - CC="musl-clang -O3 -Werror -Qunused-arguments" \ - GOCACHE="$(mktemp -d)" \ - PATH="${pkgs.pkgsStatic.musl.bin}/bin:$PATH" \ - DESTDIR="$out" \ - ./all.sh - ''; - } - ); - - devShells = forAllSystems ( - system: - let - inherit (self.packages.${system}) hakurei; - pkgs = nixpkgsFor.${system}; - in - { - default = pkgs.mkShell { - buildInputs = hakurei.targetPkgs; - hardeningDisable = [ "fortify" ]; - }; - withPackage = pkgs.mkShell { buildInputs = [ hakurei ] ++ hakurei.targetPkgs; }; - - vm = - let - nixos = nixpkgs.lib.nixosSystem { - inherit system; - modules = [ - { - environment = { - systemPackages = [ - (pkgs.buildFHSEnv { - pname = "hakurei-fhs"; - inherit (hakurei) version; - targetPkgs = _: hakurei.targetPkgs; - extraOutputsToInstall = [ "dev" ]; - profile = '' - export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH" - ''; - }) - ]; - - hakurei = - let - # this is used for interactive vm testing during development, where tests might be broken - package = self.packages.${pkgs.stdenv.hostPlatform.system}.hakurei.override { - buildGo127Module = previousArgs: pkgs.pkgsStatic.buildGo127Module (previousArgs // { doCheck = false; }); - }; - in - { - inherit package; - hsuPackage = self.packages.${pkgs.stdenv.hostPlatform.system}.hsu.override { hakurei = package; }; - }; - }; - } - - ./interactive/configuration.nix - ./interactive/vm.nix - ./interactive/hakurei.nix - ./interactive/trace.nix - ./interactive/raceattr.nix - - self.nixosModules.hakurei - home-manager.nixosModules.home-manager - ]; - }; - in - pkgs.mkShell { - buildInputs = [ nixos.config.system.build.vm ]; - shellHook = "exec run-nixos-vm $@"; - }; - - generateDoc = - let - inherit (pkgs) lib; - - doc = - let - eval = lib.evalModules { - specialArgs = { - inherit pkgs; - }; - modules = [ (import ./options.nix self.packages) ]; - }; - cleanEval = lib.filterAttrsRecursive (n: _: n != "_module") eval; - in - pkgs.nixosOptionsDoc { inherit (cleanEval) options; }; - docText = pkgs.runCommand "hakurei-module-docs.md" { } '' - cat ${doc.optionsCommonMark} > $out - sed -i '/*Declared by:*/,+1 d' $out - ''; - in - pkgs.mkShell { - shellHook = '' - exec cat ${docText} > options.md - ''; - }; - - generateSyscallTable = - let - GOARCH = { - x86_64-linux = "amd64"; - aarch64-linux = "arm64"; - }; - in - pkgs.mkShell { - shellHook = "exec ${pkgs.writeShellScript "generate-syscall-table" '' - set -e - ${pkgs.perl}/bin/perl \ - container/std/mksysnum_linux.pl \ - ${pkgs.linuxHeaders}/include/asm/unistd_64.h | \ - ${pkgs.go}/bin/gofmt > \ - container/std/syscall_linux_${GOARCH.${system}}.go - ''}"; - }; - } - ); - }; -} diff --git a/test/hsu.nix b/test/hsu.nix deleted file mode 100644 index 7acb3529..00000000 --- a/test/hsu.nix +++ /dev/null @@ -1,23 +0,0 @@ -{ - lib, - buildGoModule, - hakurei ? abort "hakurei package required", -}: - -buildGoModule { - pname = "${hakurei.pname}-hsu"; - inherit (hakurei) version; - - src = ../cmd/hsu; - inherit (hakurei) vendorHash; - env.CGO_ENABLED = 0; - - preBuild = '' - go mod init hsu >& /dev/null - ''; - - ldflags = lib.attrsets.foldlAttrs ( - ldflags: name: value: - ldflags ++ [ "-X main.${name}=${value}" ] - ) [ "-s -w" ] { hakureiPath = "${hakurei}/libexec/hakurei"; }; -} diff --git a/test/interactive/configuration.nix b/test/interactive/configuration.nix deleted file mode 100644 index 9d1bddd8..00000000 --- a/test/interactive/configuration.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ pkgs, ... }: -{ - system.stateVersion = "23.05"; - - users.users = { - alice = { - isNormalUser = true; - description = "Alice Foobar"; - password = "foobar"; - uid = 1000; - extraGroups = [ "wheel" ]; - }; - untrusted = { - isNormalUser = true; - description = "Untrusted user"; - password = "foobar"; - uid = 1001; - }; - }; - - home-manager.users.alice.home.stateVersion = "24.11"; - - security = { - sudo.wheelNeedsPassword = false; - rtkit.enable = true; - pam.loginLimits = [ - { - domain = "@users"; - item = "rtprio"; - type = "-"; - value = 1; - } - ]; - }; - - services = { - getty.autologinUser = "alice"; - pipewire = { - enable = true; - alsa.enable = true; - alsa.support32Bit = true; - pulse.enable = true; - jack.enable = true; - }; - }; - - environment.variables = { - SWAYSOCK = "/tmp/sway-ipc.sock"; - WLR_RENDERER = "pixman"; - }; - - programs = { - sway.enable = true; - - bash.loginShellInit = '' - if [ "$(tty)" = "/dev/tty1" ]; then - set -e - - mkdir -p ~/.config/sway - (sed s/Mod4/Mod1/ /etc/sway/config && - echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill') > ~/.config/sway/config - - sway --validate - systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok - fi - ''; - }; -} diff --git a/test/interactive/hakurei.nix b/test/interactive/hakurei.nix deleted file mode 100644 index ef5d0ada..00000000 --- a/test/interactive/hakurei.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ pkgs, ... }: -{ - environment.hakurei = rec { - enable = true; - stateDir = "/var/lib/hakurei"; - sharefs.source = "${stateDir}/sdcard"; - users.alice = 0; - apps = { - "cat.gensokyo.extern.foot.noEnablements" = { - name = "ne-foot"; - identity = 1; - shareUid = true; - verbose = true; - share = pkgs.foot; - packages = [ pkgs.foot ]; - command = "foot"; - enablements = { - dbus = false; - pipewire = false; - }; - }; - - "cat.gensokyo.extern.foot.badDaemon" = { - name = "bd-foot"; - identity = 1; - shareUid = true; - verbose = true; - share = pkgs.foot; - packages = [ pkgs.foot ]; - command = "foot"; - enablements = { - dbus = false; - }; - extraPaths = [ - { - type = "daemon"; - dst = "/proc/nonexistent"; - path = "/usr/bin/env"; - args = [ "false" ]; - } - ]; - }; - }; - - extraHomeConfig.home.stateVersion = "23.05"; - }; -} diff --git a/test/interactive/raceattr.nix b/test/interactive/raceattr.nix deleted file mode 100644 index de54f4cf..00000000 --- a/test/interactive/raceattr.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ lib, pkgs, ... }: -{ - security.wrappers.raceattr = - let - inherit (pkgs) buildGoModule; - in - { - setuid = true; - owner = "root"; - group = "root"; - source = "${ - (buildGoModule rec { - name = "raceattr"; - pname = name; - tags = [ "raceattr" ]; - - src = builtins.path { - name = "${pname}-src"; - path = lib.cleanSource ../sharefs; - filter = path: type: (type == "directory") || (type == "regular" && lib.hasSuffix ".go" path); - }; - vendorHash = null; - - preBuild = '' - go mod init hakurei.app/raceattr >& /dev/null - ''; - }) - }/bin/raceattr"; - }; -} diff --git a/test/interactive/trace.nix b/test/interactive/trace.nix deleted file mode 100644 index b9ef872c..00000000 --- a/test/interactive/trace.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ lib, pkgs, ... }: -let - tracing = name: "\"/sys/kernel/debug/tracing/${name}\""; -in -{ - environment.systemPackages = [ - (pkgs.writeShellScriptBin "hakurei-set-up-tracing" '' - set -e - echo "$1" > ${tracing "set_graph_function"} - echo function_graph > ${tracing "current_tracer"} - echo funcgraph-tail > ${tracing "trace_options"} - echo funcgraph-retval > ${tracing "trace_options"} - echo nofuncgraph-cpu > ${tracing "trace_options"} - echo nofuncgraph-overhead > ${tracing "trace_options"} - echo nofuncgraph-duration > ${tracing "trace_options"} - '') - (pkgs.writeShellScriptBin "hakurei-print-trace" "exec cat ${tracing "trace"}") - (pkgs.writeShellScriptBin "hakurei-consume-trace" "exec cat ${tracing "trace_pipe"}") - ]; - - boot.kernelPatches = [ - { - name = "funcgraph-retval"; - patch = null; - structuredExtraConfig = with lib.kernel; { - FUNCTION_GRAPH_RETVAL = yes; - - RUST = lib.mkForce unset; - DRM_NOVA = lib.mkForce unset; - DRM_PANIC_SCREEN_QR_CODE = lib.mkForce unset; - NOVA_CORE = lib.mkForce unset; - }; - } - ]; -} diff --git a/test/interactive/vm.nix b/test/interactive/vm.nix deleted file mode 100644 index 522878e9..00000000 --- a/test/interactive/vm.nix +++ /dev/null @@ -1,56 +0,0 @@ -{ - virtualisation.vmVariant.virtualisation = { - memorySize = 4096; - qemu.options = [ - "-vga none -device virtio-gpu-pci" - "-smp 8" - ]; - - mountHostNixStore = true; - writableStore = true; - writableStoreUseTmpfs = false; - - sharedDirectories = { - cwd = { - target = "/mnt/.ro-cwd"; - source = ''"$OLDPWD"''; - securityModel = "none"; - }; - }; - - fileSystems = { - "/mnt/.ro-cwd".options = [ - "ro" - "noatime" - ]; - "/mnt/cwd".overlay = { - lowerdir = [ "/mnt/.ro-cwd" ]; - upperdir = "/tmp/.cwd/upper"; - workdir = "/tmp/.cwd/work"; - }; - - "/mnt/src".overlay = { - lowerdir = [ ../.. ]; - upperdir = "/tmp/.src/upper"; - workdir = "/tmp/.src/work"; - }; - }; - }; - - systemd.services = { - logrotate-checkconf.enable = false; - hakurei-src-fix-ownership = { - wantedBy = [ "multi-user.target" ]; - wants = [ "mnt-src.mount" ]; - after = [ "mnt-src.mount" ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - script = '' - chown -R alice:users /mnt/src/ - chmod -R +w /mnt/src/ - ''; - }; - }; -} diff --git a/test/internal/sandbox/assert.go b/test/internal/sandbox/assert.go deleted file mode 100644 index e6fe926b..00000000 --- a/test/internal/sandbox/assert.go +++ /dev/null @@ -1,272 +0,0 @@ -//go:build testtool - -// Package sandbox provides utilities for checking sandbox outcome. -// -// This package must never be used outside integration tests, there is a much -// better native implementation of mountinfo in the public sandbox/vfs package. -// Files in this package are excluded by the build system to prevent accidental -// misuse. -package sandbox - -import ( - "crypto/sha512" - "encoding/hex" - "encoding/json" - "errors" - "io/fs" - "log" - "net" - "os" - "path/filepath" - "syscall" -) - -var ( - assert = log.New(os.Stderr, "sandbox: ", 0) - printfFunc = assert.Printf - fatalfFunc = assert.Fatalf -) - -func printf(format string, v ...any) { printfFunc(format, v...) } -func fatalf(format string, v ...any) { fatalfFunc(format, v...) } - -type TestCase struct { - Env []string `json:"env"` - FS *FS `json:"fs"` - Mount []*MountinfoEntry `json:"mount"` - Seccomp bool `json:"seccomp"` - - TrySocket string `json:"try_socket,omitempty"` - SocketAbstract bool `json:"socket_abstract,omitempty"` - SocketPathname bool `json:"socket_pathname,omitempty"` -} - -type T struct { - FS fs.FS - - MountsPath string -} - -func (t *T) MustCheckFile(wantFilePath string) { - var want *TestCase - mustDecode(wantFilePath, &want) - t.MustCheck(want) -} - -func mustAbs(s string) string { - if !filepath.IsAbs(s) { - fatalf("[FAIL] %q is not absolute", s) - panic("unreachable") - } - return s -} - -func (t *T) MustCheck(want *TestCase) { - checkWritableDirPaths := []string{ - "/dev/shm", - "/tmp", - os.Getenv("XDG_RUNTIME_DIR"), - } - for _, a := range checkWritableDirPaths { - pathname := filepath.Join(mustAbs(a), ".hakurei-check") - if err := os.WriteFile(pathname, make([]byte, 1<<8), 0600); err != nil { - fatalf("[FAIL] %s", err) - } else if err = os.Remove(pathname); err != nil { - fatalf("[FAIL] %s", err) - } else { - printf("[ OK ] %s is writable", a) - } - } - - if want.Env != nil { - var ( - fail bool - i int - got string - ) - for i, got = range os.Environ() { - if i == len(want.Env) { - fatalf("got more than %d environment variables", len(want.Env)) - } - if got != want.Env[i] { - fail = true - printf("[FAIL] %s", got) - } else { - printf("[ OK ] %s", got) - } - } - - i++ - if i != len(want.Env) { - fatalf("got %d environment variables, want %d", i, len(want.Env)) - } - - if fail { - fatalf("[FAIL] some environment variables did not match") - } - } else { - printf("[SKIP] skipping environ check") - } - - if want.FS != nil && t.FS != nil { - if err := want.FS.Compare(".", t.FS); err != nil { - fatalf("%v", err) - } - } else { - printf("[SKIP] skipping fs check") - } - - if want.Mount != nil { - var fail bool - m := mustParseMountinfo(t.MountsPath) - i := 0 - for ent := range m.Entries() { - if i == len(want.Mount) { - fatalf("got more than %d entries", i) - } - if !ent.EqualWithIgnore(want.Mount[i], "//ignore") { - fail = true - printf("[FAIL] %s", ent) - } else { - printf("[ OK ] %s", ent) - } - - i++ - } - if err := m.Err(); err != nil { - fatalf("%v", err) - } - - if i != len(want.Mount) { - fatalf("got %d entries, want %d", i, len(want.Mount)) - } - - if fail { - fatalf("[FAIL] some mount points did not match") - } - } else { - printf("[SKIP] skipping mounts check") - } - - if want.Seccomp { - if trySyscalls() != nil { - os.Exit(1) - } - } else { - printf("[SKIP] skipping seccomp check") - } - - if want.TrySocket != "" { - abstractConn, abstractErr := net.Dial("unix", "@"+want.TrySocket) - pathnameConn, pathnameErr := net.Dial("unix", want.TrySocket) - ok := true - - if abstractErr == nil { - if err := abstractConn.Close(); err != nil { - ok = false - log.Printf("Close: %v", err) - } - } - if pathnameErr == nil { - if err := pathnameConn.Close(); err != nil { - ok = false - log.Printf("Close: %v", err) - } - } - - abstractWantErr := error(syscall.EPERM) - pathnameWantErr := error(syscall.ENOENT) - if want.SocketAbstract { - abstractWantErr = nil - } - if want.SocketPathname { - pathnameWantErr = nil - } - - if !errors.Is(abstractErr, abstractWantErr) { - ok = false - log.Printf("abstractErr: %v, want %v", abstractErr, abstractWantErr) - } - if !errors.Is(pathnameErr, pathnameWantErr) { - ok = false - log.Printf("pathnameErr: %v, want %v", pathnameErr, pathnameWantErr) - } - - if !ok { - os.Exit(1) - } - } -} - -func MustCheckFilter(pid int, want string) { - err := CheckFilter(pid, want) - if err == nil { - return - } - - perr, ok := errors.AsType[*ptraceError](err) - if !ok { - fatalf("%s", err) - } - switch perr.op { - case "PTRACE_ATTACH": - fatalf("cannot attach to process %d: %v", pid, err) - case "PTRACE_SECCOMP_GET_FILTER": - if perr.errno == syscall.ENOENT { - fatalf("seccomp filter not installed for process %d", pid) - } - fatalf("cannot get filter: %v", err) - default: - fatalf("cannot check filter: %v", err) - } - - *(*int)(nil) = 0 // not reached -} - -func CheckFilter(pid int, want string) error { - if err := ptraceAttach(pid); err != nil { - return err - } - defer func() { - if err := ptraceDetach(pid); err != nil { - printf("cannot detach from process %d: %v", pid, err) - } - }() - - h := sha512.New() - - if buf, err := getFilter[[8]byte](pid, 0); err != nil { - return err - } else { - for _, b := range buf { - h.Write(b[:]) - } - } - - if got := hex.EncodeToString(h.Sum(nil)); got != want { - printf("[FAIL] %s", got) - return syscall.ENOTRECOVERABLE - } else { - printf("[ OK ] %s", got) - return nil - } -} - -func mustDecode(wantFilePath string, v any) { - if f, err := os.Open(wantFilePath); err != nil { - fatalf("cannot open %q: %v", wantFilePath, err) - } else if err = json.NewDecoder(f).Decode(v); err != nil { - fatalf("cannot decode %q: %v", wantFilePath, err) - } else if err = f.Close(); err != nil { - fatalf("cannot close %q: %v", wantFilePath, err) - } -} - -func mustParseMountinfo(name string) *Mountinfo { - m := NewMountinfo(name) - if err := m.Parse(); err != nil { - fatalf("%v", err) - panic("unreachable") - } - return m -} diff --git a/test/internal/sandbox/assert_test.go b/test/internal/sandbox/assert_test.go deleted file mode 100644 index 012ae23d..00000000 --- a/test/internal/sandbox/assert_test.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build testtool - -package sandbox - -import ( - "encoding/json" - "os" - "path/filepath" - "testing" -) - -type F func(format string, v ...any) - -func SwapPrint(f F) (old F) { old = printfFunc; printfFunc = f; return } -func SwapFatal(f F) (old F) { old = fatalfFunc; fatalfFunc = f; return } - -func MustWantFile(t *testing.T, v any) (wantFile string) { - wantFile = filepath.Join(t.TempDir(), "want.json") - if f, err := os.OpenFile(wantFile, os.O_CREATE|os.O_WRONLY, 0400); err != nil { - t.Fatalf("cannot create %q: %v", wantFile, err) - } else if err = json.NewEncoder(f).Encode(v); err != nil { - t.Fatalf("cannot encode to %q: %v", wantFile, err) - } else if err = f.Close(); err != nil { - t.Fatalf("cannot close %q: %v", wantFile, err) - } - - t.Cleanup(func() { - if err := os.Remove(wantFile); err != nil { - t.Fatalf("cannot remove %q: %v", wantFile, err) - } - }) - - return -} diff --git a/test/internal/sandbox/fs.go b/test/internal/sandbox/fs.go deleted file mode 100644 index b37d30b9..00000000 --- a/test/internal/sandbox/fs.go +++ /dev/null @@ -1,102 +0,0 @@ -//go:build testtool - -package sandbox - -import ( - "errors" - "fmt" - "io/fs" - "path/filepath" - "strings" -) - -var ( - ErrFSBadLength = errors.New("bad dir length") - ErrFSBadData = errors.New("data differs") - ErrFSBadMode = errors.New("mode differs") - ErrFSInvalidEnt = errors.New("invalid entry condition") -) - -type FS struct { - Mode fs.FileMode `json:"mode"` - Dir map[string]*FS `json:"dir"` - Data *string `json:"data"` -} - -func printDir(prefix string, dir []fs.DirEntry) { - names := make([]string, len(dir)) - for i, ent := range dir { - name := ent.Name() - if ent.IsDir() { - name += "/" - } - names[i] = fmt.Sprintf("%q", name) - } - printf("[FAIL] d %s: %s", prefix, strings.Join(names, " ")) -} - -func (s *FS) Compare(prefix string, e fs.FS) error { - if s.Data != nil { - if s.Dir != nil { - panic("invalid state") - } - panic("invalid compare call") - } - - if s.Dir == nil { - printf("[ OK ] s %s", prefix) - return nil - } - - var dir []fs.DirEntry - if d, err := fs.ReadDir(e, prefix); err != nil { - return err - } else if len(d) != len(s.Dir) { - printDir(prefix, d) - return ErrFSBadLength - } else { - dir = d - } - - for _, got := range dir { - name := got.Name() - - if want, ok := s.Dir[name]; !ok { - printDir(prefix, dir) - return fs.ErrNotExist - } else if want.Dir != nil && !got.IsDir() { - printDir(prefix, dir) - return ErrFSInvalidEnt - } else { - name = filepath.Join(prefix, name) - - if fi, err := got.Info(); err != nil { - return err - } else if fi.Mode() != want.Mode { - printf("[FAIL] m %s: %x, want %x", - name, uint32(fi.Mode()), uint32(want.Mode)) - return ErrFSBadMode - } - - if want.Data != nil { - if want.Dir != nil { - panic("invalid state") - } - if v, err := fs.ReadFile(e, name); err != nil { - return err - } else if string(v) != *want.Data { - printf("[FAIL] f %s", name) - printf("got: %s", v) - printf("want: %s", *want.Data) - return ErrFSBadData - } - printf("[ OK ] f %s", name) - } else if err := want.Compare(name, e); err != nil { - return err - } - } - } - printf("[ OK ] d %s", prefix) - - return nil -} diff --git a/test/internal/sandbox/fs_test.go b/test/internal/sandbox/fs_test.go deleted file mode 100644 index a7813ee5..00000000 --- a/test/internal/sandbox/fs_test.go +++ /dev/null @@ -1,80 +0,0 @@ -//go:build testtool - -package sandbox_test - -import ( - "errors" - "fmt" - "io/fs" - "strings" - "testing" - "testing/fstest" - - "hakurei.app/test/internal/sandbox" -) - -var ( - fsPasswdSample = "u0_a20:x:65534:65534:Hakurei:/var/lib/persist/module/hakurei/u0/a20:/run/current-system/sw/bin/zsh" - fsGroupSample = "hakurei:x:65534:" -) - -func TestCompare(t *testing.T) { - testCases := []struct { - name string - - sample fstest.MapFS - want *sandbox.FS - wantOut string - wantErr error - }{ - {"skip", fstest.MapFS{}, &sandbox.FS{}, "[ OK ] s .\x00", nil}, - {"simple pass", fstest.MapFS{".hakurei": {Mode: 0x800001ed}}, - &sandbox.FS{Dir: map[string]*sandbox.FS{".hakurei": {Mode: 0x800001ed}}}, - "[ OK ] s .hakurei\x00[ OK ] d .\x00", nil}, - {"bad length", fstest.MapFS{".hakurei": {Mode: 0x800001ed}}, - &sandbox.FS{Dir: make(map[string]*sandbox.FS)}, - "[FAIL] d .: \".hakurei/\"\x00", sandbox.ErrFSBadLength}, - {"top level bad mode", fstest.MapFS{".hakurei": {Mode: 0x800001ed}}, - &sandbox.FS{Dir: map[string]*sandbox.FS{".hakurei": {Mode: 0xdeadbeef}}}, - "[FAIL] m .hakurei: 800001ed, want deadbeef\x00", sandbox.ErrFSBadMode}, - {"invalid entry condition", fstest.MapFS{"test": {Data: []byte{'0'}, Mode: 0644}}, - &sandbox.FS{Dir: map[string]*sandbox.FS{"test": {Dir: make(map[string]*sandbox.FS)}}}, - "[FAIL] d .: \"test\"\x00", sandbox.ErrFSInvalidEnt}, - {"nonexistent", fstest.MapFS{"test": {Data: []byte{'0'}, Mode: 0644}}, - &sandbox.FS{Dir: map[string]*sandbox.FS{".test": {}}}, - "[FAIL] d .: \"test\"\x00", fs.ErrNotExist}, - {"file", fstest.MapFS{"etc": {Mode: 0x800001c0}, - "etc/passwd": {Data: []byte(fsPasswdSample), Mode: 0644}, - "etc/group": {Data: []byte(fsGroupSample), Mode: 0644}, - }, &sandbox.FS{Dir: map[string]*sandbox.FS{"etc": {Mode: 0x800001c0, Dir: map[string]*sandbox.FS{ - "passwd": {Mode: 0x1a4, Data: &fsPasswdSample}, - "group": {Mode: 0x1a4, Data: &fsGroupSample}, - }}}}, "[ OK ] f etc/group\x00[ OK ] f etc/passwd\x00[ OK ] d etc\x00[ OK ] d .\x00", nil}, - {"file differ", fstest.MapFS{"etc": {Mode: 0x800001c0}, - "etc/passwd": {Data: []byte(fsPasswdSample), Mode: 0644}, - "etc/group": {Data: []byte(fsGroupSample), Mode: 0644}, - }, &sandbox.FS{Dir: map[string]*sandbox.FS{"etc": {Mode: 0x800001c0, Dir: map[string]*sandbox.FS{ - "passwd": {Mode: 0x1a4, Data: &fsGroupSample}, - "group": {Mode: 0x1a4, Data: &fsGroupSample}, - }}}}, "[ OK ] f etc/group\x00[FAIL] f etc/passwd\x00got: u0_a20:x:65534:65534:Hakurei:/var/lib/persist/module/hakurei/u0/a20:/run/current-system/sw/bin/zsh\x00want: hakurei:x:65534:\x00", sandbox.ErrFSBadData}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - gotOut := new(strings.Builder) - oldPrint := sandbox.SwapPrint(func(format string, v ...any) { _, _ = fmt.Fprintf(gotOut, format+"\x00", v...) }) - t.Cleanup(func() { sandbox.SwapPrint(oldPrint) }) - - err := tc.want.Compare(".", tc.sample) - if !errors.Is(err, tc.wantErr) { - t.Errorf("Compare: error = %v; wantErr %v", - err, tc.wantErr) - } - - if gotOut.String() != tc.wantOut { - t.Errorf("Compare: output %q; want %q", - gotOut, tc.wantOut) - } - }) - } -} diff --git a/test/internal/sandbox/mount.go b/test/internal/sandbox/mount.go deleted file mode 100644 index 791a68b9..00000000 --- a/test/internal/sandbox/mount.go +++ /dev/null @@ -1,159 +0,0 @@ -//go:build testtool - -package sandbox - -/* -#cgo linux pkg-config: --static mount - -#include <stdlib.h> -#include <stdio.h> -#include <libmount.h> - -const char *HAKUREI_MOUNTINFO_PATH = "/proc/self/mountinfo"; -*/ -import "C" - -import ( - "errors" - "fmt" - "iter" - "runtime" - "sync" - "unsafe" -) - -var ( - ErrMountinfoParse = errors.New("invalid mountinfo records") - ErrMountinfoIter = errors.New("cannot allocate iterator") - ErrMountinfoFault = errors.New("cannot iterate on filesystems") -) - -type ( - Mountinfo struct { - mu sync.RWMutex - p string - err error - - tb *C.struct_libmnt_table - itr *C.struct_libmnt_iter - - fs *C.struct_libmnt_fs - } - - // MountinfoEntry represents deterministic mountinfo parts of a libmnt_fs entry. - MountinfoEntry struct { - // mount ID: a unique ID for the mount (may be reused after umount(2)). - ID int `json:"id"` - // parent ID: the ID of the parent mount (or of self for the root of this mount namespace's mount tree). - Parent int `json:"parent"` - // root: the pathname of the directory in the filesystem which forms the root of this mount. - Root string `json:"root"` - // mount point: the pathname of the mount point relative to the process's root directory. - Target string `json:"target"` - // mount options: per-mount options (see mount(2)). - VfsOptstr string `json:"vfs_optstr"` - // filesystem type: the filesystem type in the form "type[.subtype]". - FsType string `json:"fstype"` - // mount source: filesystem-specific information or "none". - Source string `json:"source"` - // super options: per-superblock options (see mount(2)). - FsOptstr string `json:"fs_optstr"` - } -) - -func (m *Mountinfo) copy(v *MountinfoEntry) { - if m.fs == nil { - panic("invalid entry") - } - v.ID = int(C.mnt_fs_get_id(m.fs)) - v.Parent = int(C.mnt_fs_get_parent_id(m.fs)) - v.Root = C.GoString(C.mnt_fs_get_root(m.fs)) - v.Target = C.GoString(C.mnt_fs_get_target(m.fs)) - v.VfsOptstr = C.GoString(C.mnt_fs_get_vfs_options(m.fs)) - v.FsType = C.GoString(C.mnt_fs_get_fstype(m.fs)) - v.Source = C.GoString(C.mnt_fs_get_source(m.fs)) - v.FsOptstr = C.GoString(C.mnt_fs_get_fs_options(m.fs)) -} - -func NewMountinfo(p string) *Mountinfo { m := new(Mountinfo); m.p = p; return m } - -func (m *Mountinfo) Err() error { m.mu.RLock(); defer m.mu.RUnlock(); return m.err } - -func (m *Mountinfo) Parse() error { - m.mu.Lock() - defer m.mu.Unlock() - - if m.tb != nil { - panic("open called twice") - } - - if m.p == "" { - m.tb = C.mnt_new_table_from_file(C.HAKUREI_MOUNTINFO_PATH) - } else { - name := C.CString(m.p) - m.tb = C.mnt_new_table_from_file(name) - C.free(unsafe.Pointer(name)) - } - if m.tb == nil { - return ErrMountinfoParse - } - m.itr = C.mnt_new_iter(C.MNT_ITER_FORWARD) - if m.itr == nil { - C.mnt_unref_table(m.tb) - return ErrMountinfoIter - } - - runtime.SetFinalizer(m, (*Mountinfo).Unref) - return nil -} - -func (m *Mountinfo) Unref() { - m.mu.Lock() - defer m.mu.Unlock() - - if m.tb == nil { - panic("unref called before parse") - } - - C.mnt_unref_table(m.tb) - C.mnt_free_iter(m.itr) - runtime.SetFinalizer(m, nil) -} - -func (m *Mountinfo) Entries() iter.Seq[*MountinfoEntry] { - return func(yield func(*MountinfoEntry) bool) { - m.mu.Lock() - defer m.mu.Unlock() - - C.mnt_reset_iter(m.itr, -1) - - var rc C.int - ent := new(MountinfoEntry) - for rc = C.mnt_table_next_fs(m.tb, m.itr, &m.fs); rc == 0; rc = C.mnt_table_next_fs(m.tb, m.itr, &m.fs) { - m.copy(ent) - if !yield(ent) { - return - } - } - if rc < 0 { - m.err = ErrMountinfoFault - return - } - } -} - -func (e *MountinfoEntry) EqualWithIgnore(want *MountinfoEntry, ignore string) bool { - return (e.ID == want.ID || want.ID == -1) && - (e.Parent == want.Parent || want.Parent == -1) && - (e.Root == want.Root || want.Root == ignore) && - (e.Target == want.Target || want.Target == ignore) && - (e.VfsOptstr == want.VfsOptstr || want.VfsOptstr == ignore) && - (e.FsType == want.FsType || want.FsType == ignore) && - (e.Source == want.Source || want.Source == ignore) && - (e.FsOptstr == want.FsOptstr || want.FsOptstr == ignore) -} - -func (e *MountinfoEntry) String() string { - return fmt.Sprintf("%d %d %s %s %s %s %s %s", - e.ID, e.Parent, e.Root, e.Target, e.VfsOptstr, e.FsType, e.Source, e.FsOptstr) -} diff --git a/test/internal/sandbox/mount_test.go b/test/internal/sandbox/mount_test.go deleted file mode 100644 index a565b0a0..00000000 --- a/test/internal/sandbox/mount_test.go +++ /dev/null @@ -1,144 +0,0 @@ -//go:build testtool - -package sandbox_test - -import ( - "os" - "path/filepath" - "testing" - - "hakurei.app/test/internal/sandbox" -) - -func TestMountinfo(t *testing.T) { - testCases := []struct { - name string - - sample string - want []*sandbox.MountinfoEntry - }{ - {"util-linux", `15 20 0:3 / /proc rw,relatime - proc /proc rw -16 20 0:15 / /sys rw,relatime - sysfs /sys rw -17 20 0:5 / /dev rw,relatime - devtmpfs udev rw,size=1983516k,nr_inodes=495879,mode=755 -18 17 0:10 / /dev/pts rw,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000 -19 17 0:16 / /dev/shm rw,relatime - tmpfs tmpfs rw -20 1 8:4 / / rw,noatime - ext3 /dev/sda4 rw,errors=continue,user_xattr,acl,barrier=0,data=ordered -21 16 0:17 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - tmpfs tmpfs rw,mode=755 -22 21 0:18 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd -23 21 0:19 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuset -24 21 0:20 / /sys/fs/cgroup/ns rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,ns -25 21 0:21 / /sys/fs/cgroup/cpu rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpu -26 21 0:22 / /sys/fs/cgroup/cpuacct rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,cpuacct -27 21 0:23 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory -28 21 0:24 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,devices -29 21 0:25 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer -30 21 0:26 / /sys/fs/cgroup/net_cls rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,net_cls -31 21 0:27 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,blkio -32 16 0:28 / /sys/kernel/security rw,relatime - autofs systemd-1 rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct -33 17 0:29 / /dev/hugepages rw,relatime - autofs systemd-1 rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct -34 16 0:30 / /sys/kernel/debug rw,relatime - autofs systemd-1 rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct -35 15 0:31 / /proc/sys/fs/binfmt_misc rw,relatime - autofs systemd-1 rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct -36 17 0:32 / /dev/mqueue rw,relatime - autofs systemd-1 rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct -37 15 0:14 / /proc/bus/usb rw,relatime - usbfs /proc/bus/usb rw -38 33 0:33 / /dev/hugepages rw,relatime - hugetlbfs hugetlbfs rw -39 36 0:12 / /dev/mqueue rw,relatime - mqueue mqueue rw -40 20 8:6 / /boot rw,noatime - ext3 /dev/sda6 rw,errors=continue,barrier=0,data=ordered -41 20 253:0 / /home/kzak rw,noatime - ext4 /dev/mapper/kzak-home rw,barrier=1,data=ordered -42 35 0:34 / /proc/sys/fs/binfmt_misc rw,relatime - binfmt_misc none rw -43 16 0:35 / /sys/fs/fuse/connections rw,relatime - fusectl fusectl rw -44 41 0:36 / /home/kzak/.gvfs rw,nosuid,nodev,relatime - fuse.gvfs-fuse-daemon gvfs-fuse-daemon rw,user_id=500,group_id=500 -45 20 0:37 / /var/lib/nfs/rpc_pipefs rw,relatime - rpc_pipefs sunrpc rw -47 20 0:38 / /mnt/sounds rw,relatime - cifs //foo.home/bar/ rw,unc=\\foo.home\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344 -49 20 0:56 / /mnt/test/foobar rw,relatime,nosymfollow shared:323 - tmpfs tmpfs rw`, []*sandbox.MountinfoEntry{ - e(15, 20, "/", "/proc", "rw,relatime", "proc", "/proc", "rw"), - e(16, 20, "/", "/sys", "rw,relatime", "sysfs", "/sys", "rw"), - e(17, 20, "/", "/dev", "rw,relatime", "devtmpfs", "udev", "rw,size=1983516k,nr_inodes=495879,mode=755"), - e(18, 17, "/", "/dev/pts", "rw,relatime", "devpts", "devpts", "rw,gid=5,mode=620,ptmxmode=000"), - e(19, 17, "/", "/dev/shm", "rw,relatime", "tmpfs", "tmpfs", "rw"), - e(20, 1, "/", "/", "rw,noatime", "ext3", "/dev/sda4", "rw,errors=continue,user_xattr,acl,barrier=0,data=ordered"), - e(21, 16, "/", "/sys/fs/cgroup", "rw,nosuid,nodev,noexec,relatime", "tmpfs", "tmpfs", "rw,mode=755"), - e(22, 21, "/", "/sys/fs/cgroup/systemd", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,release_agent=/lib/systemd/systemd-cgroups-agent,name=systemd"), - e(23, 21, "/", "/sys/fs/cgroup/cpuset", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpuset"), - e(24, 21, "/", "/sys/fs/cgroup/ns", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,ns"), - e(25, 21, "/", "/sys/fs/cgroup/cpu", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpu"), - e(26, 21, "/", "/sys/fs/cgroup/cpuacct", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,cpuacct"), - e(27, 21, "/", "/sys/fs/cgroup/memory", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,memory"), - e(28, 21, "/", "/sys/fs/cgroup/devices", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,devices"), - e(29, 21, "/", "/sys/fs/cgroup/freezer", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,freezer"), - e(30, 21, "/", "/sys/fs/cgroup/net_cls", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,net_cls"), - e(31, 21, "/", "/sys/fs/cgroup/blkio", "rw,nosuid,nodev,noexec,relatime", "cgroup", "cgroup", "rw,blkio"), - e(32, 16, "/", "/sys/kernel/security", "rw,relatime", "autofs", "systemd-1", "rw,fd=22,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"), - e(33, 17, "/", "/dev/hugepages", "rw,relatime", "autofs", "systemd-1", "rw,fd=23,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"), - e(34, 16, "/", "/sys/kernel/debug", "rw,relatime", "autofs", "systemd-1", "rw,fd=24,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"), - e(35, 15, "/", "/proc/sys/fs/binfmt_misc", "rw,relatime", "autofs", "systemd-1", "rw,fd=25,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"), - e(36, 17, "/", "/dev/mqueue", "rw,relatime", "autofs", "systemd-1", "rw,fd=26,pgrp=1,timeout=300,minproto=5,maxproto=5,direct"), - e(37, 15, "/", "/proc/bus/usb", "rw,relatime", "usbfs", "/proc/bus/usb", "rw"), - e(38, 33, "/", "/dev/hugepages", "rw,relatime", "hugetlbfs", "hugetlbfs", "rw"), - e(39, 36, "/", "/dev/mqueue", "rw,relatime", "mqueue", "mqueue", "rw"), - e(40, 20, "/", "/boot", "rw,noatime", "ext3", "/dev/sda6", "rw,errors=continue,barrier=0,data=ordered"), - e(41, 20, "/", "/home/kzak", "rw,noatime", "ext4", "/dev/mapper/kzak-home", "rw,barrier=1,data=ordered"), - e(42, 35, "/", "/proc/sys/fs/binfmt_misc", "rw,relatime", "binfmt_misc", "none", "rw"), - e(43, 16, "/", "/sys/fs/fuse/connections", "rw,relatime", "fusectl", "fusectl", "rw"), - e(44, 41, "/", "/home/kzak/.gvfs", "rw,nosuid,nodev,relatime", "fuse.gvfs-fuse-daemon", "gvfs-fuse-daemon", "rw,user_id=500,group_id=500"), - e(45, 20, "/", "/var/lib/nfs/rpc_pipefs", "rw,relatime", "rpc_pipefs", "sunrpc", "rw"), - e(47, 20, "/", "/mnt/sounds", "rw,relatime", "cifs", "//foo.home/bar/", "rw,unc=\\\\foo.home\\bar,username=kzak,domain=SRGROUP,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.111.1,posixpaths,serverino,acl,rsize=16384,wsize=57344"), - e(49, 20, "/", "/mnt/test/foobar", "rw,relatime,nosymfollow", "tmpfs", "tmpfs", "rw"), - }}, - } - - for _, tc := range testCases { - name := filepath.Join(t.TempDir(), "sample") - if err := os.WriteFile(name, []byte(tc.sample), 0400); err != nil { - t.Fatalf("cannot write sample: %v", err) - } - - t.Run(tc.name, func(t *testing.T) { - m := sandbox.NewMountinfo(name) - if err := m.Parse(); err != nil { - t.Fatalf("Parse: error = %v", err) - } - - i := 0 - for ent := range m.Entries() { - if i == len(tc.want) { - t.Errorf("Entries: got more than %d entries", i) - t.FailNow() - } - if !ent.EqualWithIgnore(tc.want[i], "\x00") { - t.Errorf("Entries: entry %d\n got: %#v\nwant: %#v", i, - ent, &tc.want[i]) - t.FailNow() - } else { - t.Logf("%s", ent) - } - - i++ - } - - if err := m.Err(); err != nil { - t.Fatalf("Mountinfo: error = %v", err) - } - - m.Unref() - }) - - if err := os.Remove(name); err != nil { - t.Fatalf("cannot remove %q: %v", name, err) - } - } -} - -func e( - id, parent int, root, target, vfsOptstr string, fsType, source, fsOptstr string, -) *sandbox.MountinfoEntry { - return &sandbox.MountinfoEntry{ - ID: id, - Parent: parent, - Root: root, - Target: target, - VfsOptstr: vfsOptstr, - FsType: fsType, - Source: source, - FsOptstr: fsOptstr, - } -} diff --git a/test/internal/sandbox/ptrace.go b/test/internal/sandbox/ptrace.go deleted file mode 100644 index 8272ff5b..00000000 --- a/test/internal/sandbox/ptrace.go +++ /dev/null @@ -1,87 +0,0 @@ -//go:build testtool - -package sandbox - -import ( - "errors" - "fmt" - "syscall" - "unsafe" -) - -const ( - NULL = 0 - - PTRACE_ATTACH = 16 - PTRACE_DETACH = 17 - PTRACE_SECCOMP_GET_FILTER = 0x420c -) - -type ptraceError struct { - op string - errno syscall.Errno -} - -func (p *ptraceError) Error() string { return fmt.Sprintf("%s: %v", p.op, p.errno) } - -func (p *ptraceError) Unwrap() error { - if p.errno == 0 { - return nil - } - return p.errno -} - -func ptrace(op uintptr, pid, addr int, data unsafe.Pointer) (r uintptr, errno syscall.Errno) { - r, _, errno = syscall.Syscall6(syscall.SYS_PTRACE, op, uintptr(pid), uintptr(addr), uintptr(data), NULL, NULL) - return -} - -func ptraceAttach(pid int) error { - if _, errno := ptrace(PTRACE_ATTACH, pid, 0, nil); errno != 0 { - return &ptraceError{"PTRACE_ATTACH", errno} - } - - var status syscall.WaitStatus - for { - if _, err := syscall.Wait4(pid, &status, syscall.WALL, nil); err != nil { - if errors.Is(err, syscall.EINTR) { - continue - } - fatalf("cannot waitpid: %v", err) - } - break - } - - return nil -} - -func ptraceDetach(pid int) error { - if _, errno := ptrace(PTRACE_DETACH, pid, 0, nil); errno != 0 { - return &ptraceError{"PTRACE_DETACH", errno} - } - return nil -} - -type sockFilter struct { /* Filter block */ - code uint16 /* Actual filter code */ - jt uint8 /* Jump true */ - jf uint8 /* Jump false */ - k uint32 /* Generic multiuse field */ -} - -func getFilter[T comparable](pid, index int) ([]T, error) { - if s := unsafe.Sizeof(*new(T)); s != 8 { - panic(fmt.Sprintf("invalid filter block size %d", s)) - } - - var buf []T - if n, errno := ptrace(PTRACE_SECCOMP_GET_FILTER, pid, index, nil); errno != 0 { - return nil, &ptraceError{"PTRACE_SECCOMP_GET_FILTER", errno} - } else { - buf = make([]T, n) - } - if _, errno := ptrace(PTRACE_SECCOMP_GET_FILTER, pid, index, unsafe.Pointer(&buf[0])); errno != 0 { - return nil, &ptraceError{"PTRACE_SECCOMP_GET_FILTER", errno} - } - return buf, nil -} diff --git a/test/internal/sandbox/seccomp.go b/test/internal/sandbox/seccomp.go deleted file mode 100644 index 7df781d2..00000000 --- a/test/internal/sandbox/seccomp.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build testtool - -package sandbox - -import ( - "os" - "syscall" -) - -/* -#include <sys/quota.h> -*/ -import "C" - -func trySyscalls() error { - testCases := []struct { - name string - errno syscall.Errno - - trap, a1, a2, a3, a4, a5, a6 uintptr - }{ - {"syslog", syscall.EPERM, syscall.SYS_SYSLOG, 0, NULL, NULL, NULL, NULL, NULL}, - {"acct", syscall.EPERM, syscall.SYS_ACCT, 0, NULL, NULL, NULL, NULL, NULL}, - {"quotactl", syscall.EPERM, syscall.SYS_QUOTACTL, C.Q_GETQUOTA, NULL, uintptr(os.Getuid()), NULL, NULL, NULL}, - {"add_key", syscall.EPERM, syscall.SYS_ADD_KEY, NULL, NULL, NULL, NULL, NULL, NULL}, - {"keyctl", syscall.EPERM, syscall.SYS_KEYCTL, NULL, NULL, NULL, NULL, NULL, NULL}, - {"request_key", syscall.EPERM, syscall.SYS_REQUEST_KEY, NULL, NULL, NULL, NULL, NULL, NULL}, - {"move_pages", syscall.EPERM, syscall.SYS_MOVE_PAGES, uintptr(os.Getpid()), NULL, NULL, NULL, NULL, NULL}, - {"mbind", syscall.EPERM, syscall.SYS_MBIND, NULL, NULL, NULL, NULL, NULL, NULL}, - {"get_mempolicy", syscall.EPERM, syscall.SYS_GET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL}, - {"set_mempolicy", syscall.EPERM, syscall.SYS_SET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL}, - {"migrate_pages", syscall.EPERM, syscall.SYS_MIGRATE_PAGES, NULL, NULL, NULL, NULL, NULL, NULL}, - } - - for _, tc := range testCases { - if _, _, errno := syscall.Syscall6(tc.trap, tc.a1, tc.a2, tc.a3, tc.a4, tc.a5, tc.a6); errno != tc.errno { - printf("[FAIL] %s: %v, want %v", tc.name, errno, tc.errno) - return errno - } - printf("[ OK ] %s: %v", tc.name, tc.errno) - } - - return nil -} diff --git a/test/nixos.nix b/test/nixos.nix deleted file mode 100644 index 49bfffb6..00000000 --- a/test/nixos.nix +++ /dev/null @@ -1,407 +0,0 @@ -packages: -{ - lib, - pkgs, - config, - ... -}: - -let - inherit (lib) - lists - attrsets - mkMerge - mkIf - mapAttrs - foldlAttrs - optional - optionals - ; - - cfg = config.environment.hakurei; - - # userid*userOffset + appStart + appid - getsubuid = userid: appid: userid * 100000 + 10000 + appid; - getsubname = userid: appid: "u${toString userid}_a${toString appid}"; - getsubhome = userid: appid: "${cfg.stateDir}/u${toString userid}/a${toString appid}"; - - mountpoints = { - ${cfg.sharefs.name} = mkIf (cfg.sharefs.source != null) { - depends = [ cfg.sharefs.source ]; - device = "sharefs"; - fsType = "fuse.sharefs"; - noCheck = true; - options = [ - "rw" - "noexec" - "nosuid" - "nodev" - "noatime" - "allow_other" - "mkdir" - "source=${cfg.sharefs.source}" - "setuid=${toString config.users.users.${cfg.sharefs.user}.uid}" - "setgid=${toString config.users.groups.${cfg.sharefs.group}.gid}" - ]; - }; - }; -in - -{ - imports = [ (import ./options.nix packages) ]; - - options = { - # Forward declare a dummy option for VM filesystems since the real one won't exist - # unless the VM module is actually imported. - virtualisation.fileSystems = lib.mkOption { }; - }; - - config = mkIf cfg.enable { - assertions = [ - ( - let - conflictingApps = foldlAttrs ( - acc: id: app: - ( - acc - ++ foldlAttrs ( - acc': id': app': - if id == id' || app.shareUid && app'.shareUid || app.identity != app'.identity then acc' else acc' ++ [ id ] - ) [ ] cfg.apps - ) - ) [ ] cfg.apps; - in - { - assertion = (lists.length conflictingApps) == 0; - message = "the following hakurei apps have conflicting identities: " + (builtins.concatStringsSep ", " conflictingApps); - } - ) - ]; - - security.wrappers.hsu = { - source = "${cfg.hsuPackage}/bin/hsu"; - setuid = true; - owner = "root"; - group = "root"; - }; - - environment.etc.hsurc = { - mode = "0400"; - text = foldlAttrs ( - acc: username: fid: - "${toString config.users.users.${username}.uid} ${toString fid}\n" + acc - ) "" cfg.users; - }; - - environment.systemPackages = optional (cfg.sharefs.source != null) cfg.sharefs.package; - fileSystems = mountpoints; - virtualisation.fileSystems = mountpoints; - - home-manager = - let - privPackages = mapAttrs (_: userid: { - home.packages = foldlAttrs ( - acc: id: app: - [ - ( - let - extendDBusDefault = id: ext: { - filter = true; - - talk = [ "org.freedesktop.Notifications" ] ++ ext.talk; - own = [ - "${id}.*" - "org.mpris.MediaPlayer2.${id}.*" - ] - ++ ext.own; - - inherit (ext) call broadcast; - }; - dbusConfig = - let - default = { - talk = [ ]; - own = [ ]; - call = { }; - broadcast = { }; - }; - in - { - session_bus = if app.dbus.session != null then (app.dbus.session (extendDBusDefault id)) else (extendDBusDefault id default); - system_bus = app.dbus.system; - }; - command = if app.command == null then app.name else app.command; - script = if app.script == null then ("exec " + command + " $@") else app.script; - isGraphical = if app.gpu != null then app.gpu else app.enablements.wayland || app.enablements.x11; - - conf = { - inherit id; - inherit (app) identity enablements; - inherit (dbusConfig) session_bus system_bus; - direct_wayland = app.insecureWayland; - sched_policy = app.schedPolicy; - sched_priority = app.schedPriority; - groups = app.groups ++ optional (cfg.sharefs.source != null) cfg.sharefs.group; - - container = { - inherit (app) - wait_delay - devel - userns - device - tty - multiarch - env - ; - map_real_uid = app.mapRealUid; - host_net = app.hostNet; - host_abstract = app.hostAbstract; - share_runtime = app.shareRuntime; - share_tmpdir = app.shareTmpdir; - - filesystem = - let - bind = src: { - type = "bind"; - inherit src; - }; - optBind = src: { - type = "bind"; - inherit src; - optional = true; - }; - optDevBind = src: { - type = "bind"; - inherit src; - dev = true; - optional = true; - }; - in - [ - (bind "/bin") - (bind "/usr/bin") - (bind "/nix/store") - (optBind "/sys/block") - (optBind "/sys/bus") - (optBind "/sys/class") - (optBind "/sys/dev") - (optBind "/sys/devices") - ] - ++ optionals app.nix [ - (bind "/nix/var") - ] - ++ optionals isGraphical [ - (optDevBind "/dev/dri") - (optDevBind "/dev/nvidiactl") - (optDevBind "/dev/nvidia-modeset") - (optDevBind "/dev/nvidia-uvm") - (optDevBind "/dev/nvidia-uvm-tools") - (optDevBind "/dev/nvidia0") - ] - ++ optionals app.useCommonPaths cfg.commonPaths - ++ app.extraPaths - ++ [ - { - type = "bind"; - dst = "/etc/"; - src = "/etc/"; - special = true; - } - { - type = "link"; - dst = "/run/current-system"; - linkname = "/run/current-system"; - dereference = true; - } - ] - ++ optionals (isGraphical && config.hardware.graphics.enable) ( - [ - { - type = "link"; - dst = "/run/opengl-driver"; - linkname = config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver"."L+".argument; - } - ] - ++ optionals (app.multiarch && config.hardware.graphics.enable32Bit) [ - { - type = "link"; - dst = "/run/opengl-driver-32"; - linkname = config.systemd.tmpfiles.settings.graphics-driver."/run/opengl-driver-32"."L+".argument; - } - ] - ) - ++ [ - { - type = "bind"; - src = getsubhome userid app.identity; - write = true; - ensure = true; - } - ]; - - username = getsubname userid app.identity; - inherit (cfg) shell; - home = getsubhome userid app.identity; - - path = - if app.path == null then - pkgs.writeScript "${app.name}-start" '' - #!${pkgs.zsh}${pkgs.zsh.shellPath} - ${script} - '' - else - app.path; - args = if app.args == null then [ "${app.name}-start" ] else app.args; - }; - }; - - checkedConfig = - name: value: - let - file = pkgs.writeText name (builtins.toJSON value); - in - pkgs.runCommand "checked-${name}" { nativeBuildInputs = [ cfg.package ]; } '' - ln -vs ${file} "$out" - hakurei show --no-store ${file} - ''; - in - pkgs.writeShellScriptBin app.name '' - exec hakurei${if app.verbose then " -v" else ""}${if app.insecureWayland then " --insecure" else ""} run ${checkedConfig "hakurei-app-${app.name}.json" conf} $@ - '' - ) - ] - ++ ( - let - pkg = if app.share != null then app.share else pkgs.${app.name}; - copy = source: "[ -d '${source}' ] && cp -Lrv '${source}' $out/share || true"; - in - optional (app.enablements.wayland || app.enablements.x11) ( - pkgs.runCommand "${app.name}-share" { } '' - mkdir -p $out/share - ${copy "${pkg}/share/applications"} - ${copy "${pkg}/share/pixmaps"} - ${copy "${pkg}/share/icons"} - ${copy "${pkg}/share/man"} - - if test -d "$out/share/applications"; then - substituteInPlace $out/share/applications/* \ - --replace-warn '${pkg}/bin/' "" \ - --replace-warn '${pkg}/libexec/' "" - fi - '' - ) - ) - ++ acc - ) [ cfg.package ] cfg.apps; - }) cfg.users; - in - { - useUserPackages = false; # prevent users.users entries from being added - - users = - mkMerge - (foldlAttrs - ( - acc: _: fid: - foldlAttrs - ( - acc: _: app: - ( - let - key = getsubname fid app.identity; - in - { - usernames = acc.usernames // { - ${key} = true; - }; - merge = acc.merge ++ [ - { - ${key} = mkMerge ( - [ - app.extraConfig - { home.packages = app.packages; } - ] - ++ lib.optional (!attrsets.hasAttrByPath [ key ] acc.usernames) cfg.extraHomeConfig - ); - } - ]; - } - ) - ) - { - inherit (acc) usernames; - merge = acc.merge ++ [ { ${getsubname fid 0} = cfg.extraHomeConfig; } ]; - } - cfg.apps - ) - { - usernames = { }; - merge = [ privPackages ]; - } - cfg.users - ).merge; - }; - - users = - let - getuser = userid: appid: { - isSystemUser = true; - createHome = true; - description = "Hakurei subordinate user ${toString appid} (u${toString userid})"; - group = getsubname userid appid; - home = getsubhome userid appid; - uid = getsubuid userid appid; - }; - getgroup = userid: appid: { gid = getsubuid userid appid; }; - in - { - users = mkMerge ( - foldlAttrs - ( - acc: username: fid: - acc - ++ - foldlAttrs - ( - acc': _: app: - acc' ++ [ { ${getsubname fid app.identity} = getuser fid app.identity; } ] - ) - [ - { - ${getsubname fid 0} = getuser fid 0; - ${username}.extraGroups = [ cfg.sharefs.group ]; - } - ] - cfg.apps - ) - (optional (cfg.sharefs.source != null) { - ${cfg.sharefs.user} = { - uid = lib.mkDefault 1023; - inherit (cfg.sharefs) group; - isSystemUser = true; - home = cfg.sharefs.source; - }; - }) - cfg.users - ); - - groups = mkMerge ( - foldlAttrs - ( - acc: _: fid: - acc - ++ foldlAttrs ( - acc': _: app: - acc' ++ [ { ${getsubname fid app.identity} = getgroup fid app.identity; } ] - ) [ { ${getsubname fid 0} = getgroup fid 0; } ] cfg.apps - ) - (optional (cfg.sharefs.source != null) { - ${cfg.sharefs.group} = { - gid = lib.mkDefault 1023; - }; - }) - cfg.users - ); - }; - }; -} diff --git a/test/options.md b/test/options.md deleted file mode 100644 index 6f6acddd..00000000 --- a/test/options.md +++ /dev/null @@ -1,1175 +0,0 @@ -## environment\.hakurei\.enable - - - -Whether to enable hakurei\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.package - - - -The hakurei package to use\. - - - -*Type:* -package - - - -*Default:* - -```nix -<derivation hakurei-static-x86_64-unknown-linux-musl-0.4.3> -``` - - - -## environment\.hakurei\.apps - -Declaratively configured hakurei apps\. - - - -*Type:* -attribute set of (submodule) - - - -*Default:* - -```nix -{ } -``` - - - -## environment\.hakurei\.apps\.\<name>\.enablements\.dbus - - - -Whether to proxy D-Bus\. - - - -*Type:* -null or boolean - - - -*Default:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.enablements\.pipewire - - - -Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket\. - - - -*Type:* -null or boolean - - - -*Default:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.enablements\.wayland - - - -Whether to share the Wayland server via security-context-v1\. - - - -*Type:* -null or boolean - - - -*Default:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.enablements\.x11 - - - -Whether to share the X11 socket and allow connection\. - - - -*Type:* -null or boolean - - - -*Default:* - -```nix -false -``` - - - -## environment\.hakurei\.apps\.\<name>\.packages - - - -List of extra packages to install via home-manager\. - - - -*Type:* -list of package - - - -*Default:* - -```nix -[ ] -``` - - - -## environment\.hakurei\.apps\.\<name>\.args - - - -Custom args\. -Setting this to null will default to script name\. - - - -*Type:* -null or (list of string) - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.command - - - -Command to run as the target user\. -Setting this to null will default command to launcher name\. -Has no effect when script is set\. - - - -*Type:* -null or string - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.dbus\.session - - - -D-Bus session bus custom configuration\. -Setting this to null will enable built-in defaults\. - - - -*Type:* -null or (function that evaluates to a(n) anything) - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.dbus\.system - - - -D-Bus system bus custom configuration\. -Setting this to null will disable the system bus proxy\. - - - -*Type:* -null or anything - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.devel - - - -Whether to enable debugging-related kernel interfaces\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.device - - - -Whether to enable access to all devices\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.env - - - -Environment variables to set for the initial process in the sandbox\. - - - -*Type:* -null or (attribute set of string) - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.extraConfig - - - -Extra home-manager configuration\. - - - -*Type:* -anything - - - -*Default:* - -```nix -{ } -``` - - - -## environment\.hakurei\.apps\.\<name>\.extraPaths - - - -Extra paths to make available to the container\. - - - -*Type:* -list of attribute set of anything - - - -*Default:* - -```nix -[ ] -``` - - - -## environment\.hakurei\.apps\.\<name>\.gpu - - - -Target process GPU and driver access\. -Setting this to null will enable GPU whenever X or Wayland is enabled\. - - - -*Type:* -null or boolean - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.groups - - - -List of groups to inherit from the privileged user\. - - - -*Type:* -list of string - - - -*Default:* - -```nix -[ ] -``` - - - -## environment\.hakurei\.apps\.\<name>\.hostAbstract - - - -Whether to enable share abstract unix socket scope\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.hostNet - - - -Whether to enable share host net namespace\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -true -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.identity - - - -Application identity\. Identity 0 is reserved for system services\. - - - -*Type:* -integer between 1 and 9999 (both inclusive) - - - -## environment\.hakurei\.apps\.\<name>\.insecureWayland - - - -Whether to enable direct access to the Wayland socket\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.mapRealUid - - - -Whether to enable mapping to priv-user uid\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.multiarch - - - -Whether to enable multiarch kernel-level support\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.name - - - -Name of the app’s launcher script\. - - - -*Type:* -string - - - -## environment\.hakurei\.apps\.\<name>\.nix - - - -Whether to enable nix daemon access\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.path - - - -Custom executable path\. -Setting this to null will default to the start script\. - - - -*Type:* -null or string - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.schedPolicy - - - -Scheduling policy to set for the container\. -The zero value retains the current scheduling policy\. - - - -*Type:* -null or one of “fifo”, “rr”, “batch”, “idle”, “deadline”, “ext” - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.schedPriority - - - -Scheduling priority to set for the container\. - - - -*Type:* -null or integer between 1 and 99 (both inclusive) - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.script - - - -Application launch script\. - - - -*Type:* -null or string - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.share - - - -Package containing share files\. -Setting this to null will default package name to wrapper name\. - - - -*Type:* -null or package - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.apps\.\<name>\.shareRuntime - - - -Whether to enable sharing of XDG_RUNTIME_DIR between containers under the same identity\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.shareTmpdir - - - -Whether to enable sharing of TMPDIR between containers under the same identity\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.shareUid - - - -Whether to enable sharing identity with another application\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.tty - - - -Whether to enable access to the controlling terminal\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.useCommonPaths - - - -Whether to enable common extra paths\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -true -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.userns - - - -Whether to enable user namespace creation\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.verbose - - - -Whether to enable launchers with verbose output\. - - - -*Type:* -boolean - - - -*Default:* - -```nix -false -``` - - - -*Example:* - -```nix -true -``` - - - -## environment\.hakurei\.apps\.\<name>\.wait_delay - - - -Duration to wait for after interrupting a container’s initial process in nanoseconds\. -A negative value causes the container to be terminated immediately on cancellation\. -Setting this to null defaults to five seconds\. - - - -*Type:* -null or signed integer - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.commonPaths - - - -Common extra paths to make available to the container\. - - - -*Type:* -list of attribute set of anything - - - -*Default:* - -```nix -[ ] -``` - - - -## environment\.hakurei\.extraHomeConfig - - - -Extra home-manager configuration to merge with all target users\. - - - -*Type:* -anything - - - -## environment\.hakurei\.hsuPackage - - - -The hsu package to use\. - - - -*Type:* -package - - - -*Default:* - -```nix -<derivation hakurei-hsu-0.4.3> -``` - - - -## environment\.hakurei\.sharefs\.package - - - -The sharefs package to use\. - - - -*Type:* -package - - - -*Default:* - -```nix -<derivation sharefs> -``` - - - -## environment\.hakurei\.sharefs\.group - - - -Name of the group to run the sharefs daemon as\. - - - -*Type:* -string - - - -*Default:* - -```nix -"sharefs" -``` - - - -## environment\.hakurei\.sharefs\.name - - - -Host path to mount sharefs on\. - - - -*Type:* -string - - - -*Default:* - -```nix -"/sdcard" -``` - - - -## environment\.hakurei\.sharefs\.source - - - -Writable backing directory\. Setting this to null disables sharefs\. - - - -*Type:* -null or string - - - -*Default:* - -```nix -null -``` - - - -## environment\.hakurei\.sharefs\.user - - - -Name of the user to run the sharefs daemon as\. - - - -*Type:* -string - - - -*Default:* - -```nix -"sharefs" -``` - - - -## environment\.hakurei\.shell - - - -Absolute path to preferred shell\. - - - -*Type:* -string - - - -*Default:* - -```nix -"/run/current-system/sw/bin/bash" -``` - - - -## environment\.hakurei\.stateDir - - - -The state directory where app home directories are stored\. - - - -*Type:* -string - - - -## environment\.hakurei\.users - - - -Users allowed to spawn hakurei apps and their corresponding hakurei identity\. - - - -*Type:* -attribute set of integer between 0 and 99 (both inclusive) - - - -*Default:* - -```nix -{ } -``` - - diff --git a/test/options.nix b/test/options.nix deleted file mode 100644 index f624b6f5..00000000 --- a/test/options.nix +++ /dev/null @@ -1,364 +0,0 @@ -packages: -{ - lib, - pkgs, - config, - ... -}: - -let - inherit (lib) types mkOption mkEnableOption; - - cfg = config.environment.hakurei; -in - -{ - options = { - environment.hakurei = { - enable = mkEnableOption "hakurei"; - - package = mkOption { - type = types.package; - default = packages.${pkgs.stdenv.hostPlatform.system}.hakurei; - description = "The hakurei package to use."; - }; - - hsuPackage = mkOption { - type = types.package; - default = packages.${pkgs.stdenv.hostPlatform.system}.hsu; - description = "The hsu package to use."; - }; - - users = mkOption { - type = - let - inherit (types) attrsOf ints; - in - attrsOf (ints.between 0 99); - description = '' - Users allowed to spawn hakurei apps and their corresponding hakurei identity. - ''; - }; - - extraHomeConfig = mkOption { - type = types.anything; - description = '' - Extra home-manager configuration to merge with all target users. - ''; - }; - - sharefs = { - package = mkOption { - type = types.package; - default = pkgs.linkFarm "sharefs" { - "bin/sharefs" = "${cfg.package}/libexec/sharefs"; - "bin/mount.fuse.sharefs" = "${cfg.package}/libexec/sharefs"; - }; - description = "The sharefs package to use."; - }; - - user = mkOption { - type = types.str; - default = "sharefs"; - description = '' - Name of the user to run the sharefs daemon as. - ''; - }; - - group = mkOption { - type = types.str; - default = "sharefs"; - description = '' - Name of the group to run the sharefs daemon as. - ''; - }; - - name = mkOption { - type = types.str; - default = "/sdcard"; - description = '' - Host path to mount sharefs on. - ''; - }; - - source = mkOption { - type = types.nullOr types.str; - default = null; - description = '' - Writable backing directory. Setting this to null disables sharefs. - ''; - }; - }; - - apps = mkOption { - type = - let - inherit (types) - int - ints - str - bool - enum - package - anything - submodule - listOf - attrsOf - nullOr - functionTo - ; - in - attrsOf (submodule { - options = { - name = mkOption { - type = str; - description = '' - Name of the app's launcher script. - ''; - }; - - verbose = mkEnableOption "launchers with verbose output"; - - identity = mkOption { - type = ints.between 1 9999; - description = '' - Application identity. Identity 0 is reserved for system services. - ''; - }; - shareUid = mkEnableOption "sharing identity with another application"; - - packages = mkOption { - type = listOf package; - default = [ ]; - description = '' - List of extra packages to install via home-manager. - ''; - }; - - extraConfig = mkOption { - type = anything; - default = { }; - description = '' - Extra home-manager configuration. - ''; - }; - - path = mkOption { - type = nullOr str; - default = null; - description = '' - Custom executable path. - Setting this to null will default to the start script. - ''; - }; - - args = mkOption { - type = nullOr (listOf str); - default = null; - description = '' - Custom args. - Setting this to null will default to script name. - ''; - }; - - script = mkOption { - type = nullOr str; - default = null; - description = '' - Application launch script. - ''; - }; - - command = mkOption { - type = nullOr str; - default = null; - description = '' - Command to run as the target user. - Setting this to null will default command to launcher name. - Has no effect when script is set. - ''; - }; - - groups = mkOption { - type = listOf str; - default = [ ]; - description = '' - List of groups to inherit from the privileged user. - ''; - }; - - shareRuntime = mkEnableOption "sharing of XDG_RUNTIME_DIR between containers under the same identity"; - shareTmpdir = mkEnableOption "sharing of TMPDIR between containers under the same identity"; - - dbus = { - session = mkOption { - type = nullOr (functionTo anything); - default = null; - description = '' - D-Bus session bus custom configuration. - Setting this to null will enable built-in defaults. - ''; - }; - - system = mkOption { - type = nullOr anything; - default = null; - description = '' - D-Bus system bus custom configuration. - Setting this to null will disable the system bus proxy. - ''; - }; - }; - - env = mkOption { - type = nullOr (attrsOf str); - default = null; - description = '' - Environment variables to set for the initial process in the sandbox. - ''; - }; - - wait_delay = mkOption { - type = nullOr int; - default = null; - description = '' - Duration to wait for after interrupting a container's initial process in nanoseconds. - A negative value causes the container to be terminated immediately on cancellation. - Setting this to null defaults to five seconds. - ''; - }; - - devel = mkEnableOption "debugging-related kernel interfaces"; - userns = mkEnableOption "user namespace creation"; - tty = mkEnableOption "access to the controlling terminal"; - multiarch = mkEnableOption "multiarch kernel-level support"; - - hostNet = mkEnableOption "share host net namespace" // { - default = true; - }; - hostAbstract = mkEnableOption "share abstract unix socket scope"; - - schedPolicy = mkOption { - type = nullOr (enum [ - "fifo" - "rr" - "batch" - "idle" - "deadline" - "ext" - ]); - default = null; - description = '' - Scheduling policy to set for the container. - The zero value retains the current scheduling policy. - ''; - }; - schedPriority = mkOption { - type = nullOr (ints.between 1 99); - default = null; - description = '' - Scheduling priority to set for the container. - ''; - }; - - nix = mkEnableOption "nix daemon access"; - mapRealUid = mkEnableOption "mapping to priv-user uid"; - device = mkEnableOption "access to all devices"; - insecureWayland = mkEnableOption "direct access to the Wayland socket"; - - gpu = mkOption { - type = nullOr bool; - default = null; - description = '' - Target process GPU and driver access. - Setting this to null will enable GPU whenever X or Wayland is enabled. - ''; - }; - - useCommonPaths = mkEnableOption "common extra paths" // { - default = true; - }; - - extraPaths = mkOption { - type = listOf (attrsOf anything); - default = [ ]; - description = '' - Extra paths to make available to the container. - ''; - }; - - enablements = { - wayland = mkOption { - type = nullOr bool; - default = true; - description = '' - Whether to share the Wayland server via security-context-v1. - ''; - }; - - x11 = mkOption { - type = nullOr bool; - default = false; - description = '' - Whether to share the X11 socket and allow connection. - ''; - }; - - dbus = mkOption { - type = nullOr bool; - default = true; - description = '' - Whether to proxy D-Bus. - ''; - }; - - pipewire = mkOption { - type = nullOr bool; - default = true; - description = '' - Whether to share the PipeWire server via pipewire-pulse on a SecurityContext socket. - ''; - }; - }; - - share = mkOption { - type = nullOr package; - default = null; - description = '' - Package containing share files. - Setting this to null will default package name to wrapper name. - ''; - }; - }; - }); - default = { }; - description = '' - Declaratively configured hakurei apps. - ''; - }; - - commonPaths = mkOption { - type = types.listOf (types.attrsOf types.anything); - default = [ ]; - description = '' - Common extra paths to make available to the container. - ''; - }; - - shell = mkOption { - type = types.str; - default = "/run/current-system/sw/bin/bash"; - description = '' - Absolute path to preferred shell. - ''; - }; - - stateDir = mkOption { - type = types.str; - description = '' - The state directory where app home directories are stored. - ''; - }; - }; - }; -} diff --git a/test/package.nix b/test/package.nix deleted file mode 100644 index e68420e3..00000000 --- a/test/package.nix +++ /dev/null @@ -1,144 +0,0 @@ -{ - lib, - stdenv, - buildGo127Module, - makeBinaryWrapper, - xdg-dbus-proxy, - pkg-config, - libffi, - libseccomp, - acl, - wayland, - wayland-protocols, - wayland-scanner, - - libxcb, - libxau, - libxdmcp, - - # for sharefs - fuse3, - - # for passthru.buildInputs - go_1_27, - clang, - xorgproto, - - # for check - util-linux, - nettools, - - glibc, # for ldd - withStatic ? stdenv.hostPlatform.isStatic, -}: - -buildGo127Module rec { - pname = "hakurei"; - version = with lib.strings; removePrefix "v" (trim (builtins.readFile ../cmd/dist/VERSION)); - - srcFiltered = builtins.path { - name = "${pname}-src"; - path = lib.cleanSource ../.; - filter = path: type: !(type == "regular" && (lib.hasSuffix ".nix" path || lib.hasSuffix ".py" path)) && !(type == "directory" && lib.hasSuffix "/test" path) && !(type == "directory" && lib.hasSuffix "/cmd/hsu" path); - }; - vendorHash = null; - - src = stdenv.mkDerivation { - name = "${pname}-src-full"; - inherit version; - enableParallelBuilding = true; - src = srcFiltered; - - buildInputs = [ - wayland - wayland-protocols - ]; - - nativeBuildInputs = [ - go_1_27 - pkg-config - wayland-scanner - ]; - - buildPhase = "GOCACHE=$(mktemp -d) go generate ./..."; - installPhase = "cp -r . $out"; - }; - - ldflags = - lib.attrsets.foldlAttrs - ( - ldflags: name: value: - ldflags ++ [ "-X hakurei.app/internal/info.${name}=${value}" ] - ) - ( - [ "-s -w" ] - ++ lib.optionals withStatic [ - "-linkmode external" - "-extldflags \"-static\"" - ] - ) - { - buildVersion = "v${version}"; - hakureiPath = "${placeholder "out"}/libexec/hakurei"; - hsuPath = "/run/wrappers/bin/hsu"; - }; - - env = { - # use clang instead of gcc - CC = "clang -O3 -Werror"; - }; - - buildInputs = [ - libffi - libseccomp - fuse3 - acl - wayland - - libxcb - libxau - libxdmcp - ]; - - nativeBuildInputs = [ - pkg-config - makeBinaryWrapper - - # for container example - nettools - ]; - - postInstall = - let - appPackages = [ - glibc - xdg-dbus-proxy - ]; - in - '' - install -D --target-directory=$out/share/zsh/site-functions cmd/dist/comp/* - - mkdir "$out/libexec" - mv "$out"/bin/* "$out/libexec/" - - makeBinaryWrapper "$out/libexec/hakurei" "$out/bin/hakurei" \ - --inherit-argv0 --prefix PATH : ${lib.makeBinPath appPackages} - ''; - - passthru = { - go = go_1_27; - - targetPkgs = [ - go_1_27 - clang - xorgproto - util-linux - - # for go generate - wayland-protocols - wayland-scanner - ] - ++ buildInputs - ++ nativeBuildInputs; - }; -} diff --git a/test/sandbox/case/default.nix b/test/sandbox/case/default.nix deleted file mode 100644 index 337f4bf2..00000000 --- a/test/sandbox/case/default.nix +++ /dev/null @@ -1,97 +0,0 @@ -system: lib: testProgram: -let - fs = mode: dir: data: { - mode = lib.fromHexString mode; - inherit - dir - data - ; - }; - - ignore = "//ignore"; - - ent = root: target: vfs_optstr: fstype: source: fs_optstr: { - id = -1; - parent = -1; - inherit - root - target - vfs_optstr - fstype - source - fs_optstr - ; - }; - - importTestCase = - path: - import path { - inherit - fs - ent - ignore - system - ; - }; - - callTestCase = - path: identity: - let - tc = importTestCase path; - in - { - name = "check-sandbox-${tc.name}"; - inherit identity; - verbose = true; - inherit (tc) - tty - device - mapRealUid - useCommonPaths - userns - hostAbstract - shareRuntime - shareTmpdir - ; - enablements = { - inherit (tc) x11; - }; - share = testProgram; - packages = [ ]; - path = "${testProgram}/bin/hakurei-test"; - args = [ - "hakurei-test" - "-p" - "/var/tmp/.hakurei-check-ok.${toString identity}" - "-t" - (toString (builtins.toFile "hakurei-${tc.name}-want.json" (builtins.toJSON tc.want))) - "-s" - tc.expectedFilter.${system} - ]; - - extraPaths = - if tc.useCommonPaths then - [ ] - else - [ - { - type = "bind"; - src = "/var/tmp"; - write = true; - } - ]; - }; - - testCaseName = name: "cat.gensokyo.hakurei.test." + name; -in -{ - apps = { - ${testCaseName "preset"} = callTestCase ./preset.nix 1; - ${testCaseName "tty"} = callTestCase ./tty.nix 2; - ${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3; - ${testCaseName "device"} = callTestCase ./device.nix 4; - ${testCaseName "pdlike"} = callTestCase ./pdlike.nix 5; - }; - - pd = importTestCase ./pd.nix; -} diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix deleted file mode 100644 index 889e0a06..00000000 --- a/test/sandbox/case/device.nix +++ /dev/null @@ -1,255 +0,0 @@ -{ - fs, - ent, - ignore, - system, -}: -let - extraPaths = { - x86_64-linux = { - fd = "fd0"; - sr = { - sr0 = fs "80001ff" null null; - }; - }; - aarch64-linux = { - fd = "mtdblock0"; - sr = { }; - }; - }; -in -{ - name = "device"; - tty = false; - device = true; - mapRealUid = false; - useCommonPaths = true; - userns = false; - x11 = true; - hostAbstract = false; - shareRuntime = false; - shareTmpdir = true; - - # 0, PresetStrict - expectedFilter = { - x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735"; - aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297"; - }; - - want = { - env = [ - "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus" - "DISPLAY=unix:/tmp/.X11-unix/X0" - "HOME=/var/lib/hakurei/u0/a4" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a4" - "WAYLAND_DISPLAY=wayland-0" - "XDG_RUNTIME_DIR=/run/user/65534" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=wayland" - "PULSE_SERVER=unix:/run/user/65534/pulse/native" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { - ".ro-store" = fs "801001fd" null null; - store = fs "800001ff" null null; - } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" null null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:65534:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a4:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a4:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - nix = fs "800001c0" { store = fs "801001fd" null null; } null; - proc = fs "8000016d" null null; - run = fs "800001ed" { - current-system = fs "80001ff" null null; - opengl-driver = fs "80001ff" null null; - user = fs "800001ed" { - "65534" = fs "800001c0" { - bus = fs "10001fd" null null; - pulse = fs "800001c0" { native = fs "10001ff" null null; } null; - wayland-0 = fs "1000038" null null; - } null; - } null; - } null; - sys = fs "800001c0" { - block = fs "800001ed" ( - { - ${extraPaths.${system}.fd} = fs "80001ff" null null; - loop0 = fs "80001ff" null null; - loop1 = fs "80001ff" null null; - loop2 = fs "80001ff" null null; - loop3 = fs "80001ff" null null; - loop4 = fs "80001ff" null null; - loop5 = fs "80001ff" null null; - loop6 = fs "80001ff" null null; - loop7 = fs "80001ff" null null; - vda = fs "80001ff" null null; - } - // extraPaths.${system}.sr - ) null; - bus = fs "800001ed" null null; - class = fs "800001ed" null null; - dev = fs "800001ed" { - block = fs "800001ed" null null; - char = fs "800001ed" null null; - } null; - devices = fs "800001ed" null null; - } null; - tmp = fs "800001f8" { - ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null; - } null; - usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001c0" { - tmp = fs "801001ff" null null; - lib = fs "800001c0" { - hakurei = fs "800001c0" { - u0 = fs "800001c0" { - a4 = fs "800001c0" { - ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null; - ".config" = fs "800001ed" { - "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null; - systemd = fs "800001ed" { - user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null; - } null; - } null; - ".local" = fs "800001ed" { - state = fs "800001ed" { - ".keep" = fs "80001ff" null ""; - home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null; - nix = fs "800001ed" { - profiles = fs "800001ed" { - profile = fs "80001ff" null null; - profile-1-link = fs "80001ff" null null; - } null; - } null; - } null; - } null; - ".nix-defexpr" = fs "800001ed" { - channels = fs "80001ff" null null; - channels_root = fs "80001ff" null null; - } null; - ".nix-profile" = fs "80001ff" null null; - } null; - } null; - } null; - } null; - cache = fs "800001ed" { private = fs "800001c0" null null; } null; - } null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004") - (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw") - (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/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) - (ent "/" ignore ignore ignore ignore ignore) - (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=16384k,mode=755,uid=10004,gid=10004") - (ent "/tmp/hakurei.0/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10004,gid=10004") - (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr") - (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr") - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = false; - socket_pathname = true; - }; -} diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix deleted file mode 100644 index 1b6ef0e7..00000000 --- a/test/sandbox/case/mapuid.nix +++ /dev/null @@ -1,282 +0,0 @@ -{ - fs, - ent, - ignore, - system, -}: -let - extraPaths = { - x86_64-linux = { - fd = "fd0"; - "/dev/dri" = { - by-path = fs "800001ed" { - "pci-0000:00:09.0-card" = fs "80001ff" null null; - "pci-0000:00:09.0-render" = fs "80001ff" null null; - } null; - card0 = fs "42001b0" null null; - renderD128 = fs "42001b6" null null; - }; - sr = { - sr0 = fs "80001ff" null null; - }; - }; - aarch64-linux = { - fd = "mtdblock0"; - "/dev/dri" = null; - sr = { }; - }; - }; -in -{ - name = "mapuid"; - tty = false; - device = false; - mapRealUid = true; - useCommonPaths = true; - userns = false; - x11 = false; - hostAbstract = false; - shareRuntime = true; - shareTmpdir = true; - - # 0, PresetStrict - expectedFilter = { - x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735"; - aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297"; - }; - - want = { - env = [ - "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus" - "HOME=/var/lib/hakurei/u0/a3" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a3" - "WAYLAND_DISPLAY=wayland-0" - "XDG_RUNTIME_DIR=/run/user/1000" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=wayland" - "PULSE_SERVER=unix:/run/user/1000/pulse/native" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { - ".ro-store" = fs "801001fd" null null; - store = fs "800001ff" null null; - } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" { - core = fs "80001ff" null null; - dri = fs "800001ed" extraPaths.${system}."/dev/dri" null; - fd = fs "80001ff" null null; - full = fs "42001b6" null null; - mqueue = fs "801001ff" { } null; - null = fs "42001b6" null ""; - ptmx = fs "80001ff" null null; - pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; - random = fs "42001b6" null null; - shm = fs "801001ff" { } null; - stderr = fs "80001ff" null null; - stdin = fs "80001ff" null null; - stdout = fs "80001ff" null null; - tty = fs "42001b6" null null; - urandom = fs "42001b6" null null; - zero = fs "42001b6" null null; - } null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:100:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a3:x:1000:100:Hakurei:/var/lib/hakurei/u0/a3:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - nix = fs "800001c0" { store = fs "801001fd" null null; } null; - proc = fs "8000016d" null null; - run = fs "800001ed" { - current-system = fs "80001ff" null null; - opengl-driver = fs "80001ff" null null; - user = fs "800001ed" { - "1000" = fs "800001f8" { - bus = fs "10001fd" null null; - pulse = fs "800001c0" { native = fs "10001ff" null null; } null; - wayland-0 = fs "1000038" null null; - } null; - } null; - } null; - sys = fs "800001c0" { - block = fs "800001ed" ( - { - ${extraPaths.${system}.fd} = fs "80001ff" null null; - loop0 = fs "80001ff" null null; - loop1 = fs "80001ff" null null; - loop2 = fs "80001ff" null null; - loop3 = fs "80001ff" null null; - loop4 = fs "80001ff" null null; - loop5 = fs "80001ff" null null; - loop6 = fs "80001ff" null null; - loop7 = fs "80001ff" null null; - vda = fs "80001ff" null null; - } - // extraPaths.${system}.sr - ) null; - bus = fs "800001ed" null null; - class = fs "800001ed" null null; - dev = fs "800001ed" { - block = fs "800001ed" null null; - char = fs "800001ed" null null; - } null; - devices = fs "800001ed" null null; - } null; - tmp = fs "800001f8" { } null; - usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001c0" { - tmp = fs "801001ff" null null; - lib = fs "800001c0" { - hakurei = fs "800001c0" { - u0 = fs "800001c0" { - a3 = fs "800001c0" { - ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null; - ".config" = fs "800001ed" { - "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null; - systemd = fs "800001ed" { - user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null; - } null; - } null; - ".local" = fs "800001ed" { - state = fs "800001ed" { - ".keep" = fs "80001ff" null ""; - home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null; - nix = fs "800001ed" { - profiles = fs "800001ed" { - profile = fs "80001ff" null null; - profile-1-link = fs "80001ff" null null; - } null; - } null; - } null; - } null; - ".nix-defexpr" = fs "800001ed" { - channels = fs "80001ff" null null; - channels_root = fs "80001ff" null null; - } null; - ".nix-profile" = fs "80001ff" null null; - } null; - } null; - } null; - } null; - cache = fs "800001ed" { private = fs "800001c0" null null; } null; - } null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003") - (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw") - (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=10003,gid=10003") - (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/urandom" "/dev/urandom" "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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw") - (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=16384k,mode=755,uid=10003,gid=10003") - (ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10003,gid=10003") - (ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr") - (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr") - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = false; - socket_pathname = false; - }; -} diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix deleted file mode 100644 index 25f42979..00000000 --- a/test/sandbox/case/pd.nix +++ /dev/null @@ -1,206 +0,0 @@ -{ - fs, - ent, - ignore, - ... -}: -{ - # 0, PresetExt | PresetDenyDevel - expectedFilter = { - x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a"; - aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980"; - }; - - want = { - env = [ - "HOME=/var/lib/hakurei/u0/a0" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a0" - "XDG_RUNTIME_DIR=/run/user/65534" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=tty" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" { - console = fs "4200190" null null; - core = fs "80001ff" null null; - fd = fs "80001ff" null null; - full = fs "42001b6" null null; - kvm = fs "42001b6" null null; - mqueue = fs "801001ff" { } null; - null = fs "42001b6" null ""; - ptmx = fs "80001ff" null null; - pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; - random = fs "42001b6" null null; - shm = fs "801001ff" { } null; - stderr = fs "80001ff" null null; - stdin = fs "80001ff" null null; - stdout = fs "80001ff" null null; - tty = fs "42001b6" null null; - urandom = fs "42001b6" null null; - zero = fs "42001b6" null null; - } null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:65534:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a0:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a0:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - home = fs "800001ed" { alice = fs "800001c0" null null; } null; - lib64 = fs "800001ed" { "ld-linux-x86-64.so.2" = fs "80001ff" null null; } null; - "lost+found" = fs "800001c0" null null; - nix = fs "800001ed" { - ".ro-store" = fs "801001fd" null null; - ".rw-store" = fs "800001ed" null null; - store = fs "801001fd" null null; - var = fs "800001ed" { - log = fs "800001ed" null null; - nix = fs "800001ed" null null; - } null; - } null; - proc = fs "8000016d" null null; - root = fs "800001c0" null null; - run = fs "800001ed" null null; - srv = fs "800001ed" { } null; - sys = fs "8000016d" null null; - tmp = fs "800001f8" { } null; - usr = fs "800001ed" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001ed" null null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000") - (ent "/bin" "/bin" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/home" "/home" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/lib64" "/lib64" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/lost+found" "/lost+found" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/nix" "/nix" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - # systemd nondeterminism: ro-store rw-store - (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore) - (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore) - (ent "/" "/nix/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/root" "/root" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/run" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore) - (ent "/" "/run/keys" "rw,nosuid,nodev,relatime" "ramfs" "ramfs" "rw,mode=750") - (ent "/" "/run/credentials/systemd-journald.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap") - (ent "/" "/run/wrappers" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore) - (ent "/" "/run/credentials/getty@tty1.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap") - (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore) - (ent "/srv" "/srv" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/sys" "rw,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/" "/sys/kernel/security" "rw,nosuid,nodev,noexec,relatime" "securityfs" "securityfs" "rw") - (ent "/../../.." "/sys/fs/cgroup" "rw,nosuid,nodev,noexec,relatime" "cgroup2" "cgroup2" "rw,nsdelegate,memory_recursiveprot,memory_hugetlb_accounting") - (ent "/" "/sys/fs/pstore" "rw,nosuid,nodev,noexec,relatime" "pstore" "none" "rw") - (ent "/" "/sys/fs/bpf" "rw,nosuid,nodev,noexec,relatime" "bpf" "bpf" "rw,mode=700") - # systemd nondeterminism: tracefs debugfs configfs fusectl - (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw") - (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw") - (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw") - (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw") - (ent "/usr" "/usr" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "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=10000,gid=10000") - (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 "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/urandom" "/dev/urandom" "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 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/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10000,gid=10000") - (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10000,gid=10000") - (ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10000,gid=10000") - (ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10000,gid=10000") - (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = true; - socket_pathname = false; - }; -} diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix deleted file mode 100644 index 7f0716fb..00000000 --- a/test/sandbox/case/pdlike.nix +++ /dev/null @@ -1,277 +0,0 @@ -{ - fs, - ent, - ignore, - system, -}: -let - extraPaths = { - x86_64-linux = { - fd = "fd0"; - "/dev/dri" = { - by-path = fs "800001ed" { - "pci-0000:00:09.0-card" = fs "80001ff" null null; - "pci-0000:00:09.0-render" = fs "80001ff" null null; - } null; - card0 = fs "42001b0" null null; - renderD128 = fs "42001b6" null null; - }; - sr = { - sr0 = fs "80001ff" null null; - }; - }; - aarch64-linux = { - fd = "mtdblock0"; - "/dev/dri" = null; - sr = { }; - }; - }; -in -{ - name = "pdlike"; - tty = true; - device = false; - mapRealUid = false; - useCommonPaths = false; - userns = true; - x11 = false; - hostAbstract = false; - shareRuntime = true; - shareTmpdir = true; - - # 0, PresetExt | PresetDenyDevel - expectedFilter = { - x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a"; - aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980"; - }; - - want = { - env = [ - "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus" - "HOME=/var/lib/hakurei/u0/a5" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a5" - "WAYLAND_DISPLAY=wayland-0" - "XDG_RUNTIME_DIR=/run/user/65534" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=wayland" - "PULSE_SERVER=unix:/run/user/65534/pulse/native" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" { - console = fs "4200190" null null; - core = fs "80001ff" null null; - dri = fs "800001ed" extraPaths.${system}."/dev/dri" null; - fd = fs "80001ff" null null; - full = fs "42001b6" null null; - mqueue = fs "801001ff" { } null; - null = fs "42001b6" null ""; - ptmx = fs "80001ff" null null; - pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; - random = fs "42001b6" null null; - shm = fs "801001ff" { } null; - stderr = fs "80001ff" null null; - stdin = fs "80001ff" null null; - stdout = fs "80001ff" null null; - tty = fs "42001b6" null null; - urandom = fs "42001b6" null null; - zero = fs "42001b6" null null; - } null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:65534:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a5:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a5:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - nix = fs "800001c0" { store = fs "801001fd" null null; } null; - proc = fs "8000016d" null null; - run = fs "800001ed" { - current-system = fs "80001ff" null null; - opengl-driver = fs "80001ff" null null; - user = fs "800001ed" { - "65534" = fs "800001f8" { - bus = fs "10001fd" null null; - pulse = fs "800001c0" { native = fs "10001ff" null null; } null; - wayland-0 = fs "1000038" null null; - } null; - } null; - } null; - sys = fs "800001c0" { - block = fs "800001ed" ( - { - ${extraPaths.${system}.fd} = fs "80001ff" null null; - loop0 = fs "80001ff" null null; - loop1 = fs "80001ff" null null; - loop2 = fs "80001ff" null null; - loop3 = fs "80001ff" null null; - loop4 = fs "80001ff" null null; - loop5 = fs "80001ff" null null; - loop6 = fs "80001ff" null null; - loop7 = fs "80001ff" null null; - vda = fs "80001ff" null null; - } - // extraPaths.${system}.sr - ) null; - bus = fs "800001ed" null null; - class = fs "800001ed" null null; - dev = fs "800001ed" { - block = fs "800001ed" null null; - char = fs "800001ed" null null; - } null; - devices = fs "800001ed" null null; - } null; - tmp = fs "800001f8" { } null; - usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001c0" { - tmp = fs "801001ff" null null; - lib = fs "800001c0" { - hakurei = fs "800001c0" { - u0 = fs "800001c0" { - a5 = fs "800001c0" { - ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null; - ".config" = fs "800001ed" { - "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null; - systemd = fs "800001ed" { - user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null; - } null; - } null; - ".local" = fs "800001ed" { - state = fs "800001ed" { - ".keep" = fs "80001ff" null ""; - home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null; - nix = fs "800001ed" { - profiles = fs "800001ed" { - profile = fs "80001ff" null null; - profile-1-link = fs "80001ff" null null; - } null; - } null; - } null; - } null; - ".nix-defexpr" = fs "800001ed" { - channels = fs "80001ff" null null; - channels_root = fs "80001ff" null null; - } null; - ".nix-profile" = fs "80001ff" null null; - } null; - } null; - } null; - } null; - } null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005") - (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw") - (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=10005,gid=10005") - (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/urandom" "/dev/urandom" "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 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/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10005,gid=10005") - (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10005,gid=10005") - (ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10005,gid=10005") - (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = false; - socket_pathname = false; - }; -} diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix deleted file mode 100644 index 33cc3b8b..00000000 --- a/test/sandbox/case/preset.nix +++ /dev/null @@ -1,274 +0,0 @@ -{ - fs, - ent, - ignore, - system, -}: -let - extraPaths = { - x86_64-linux = { - fd = "fd0"; - "/dev/dri" = { - by-path = fs "800001ed" { - "pci-0000:00:09.0-card" = fs "80001ff" null null; - "pci-0000:00:09.0-render" = fs "80001ff" null null; - } null; - card0 = fs "42001b0" null null; - renderD128 = fs "42001b6" null null; - }; - sr = { - sr0 = fs "80001ff" null null; - }; - }; - aarch64-linux = { - fd = "mtdblock0"; - "/dev/dri" = null; - sr = { }; - }; - }; -in -{ - name = "preset"; - tty = false; - device = false; - mapRealUid = false; - useCommonPaths = false; - userns = false; - x11 = false; - hostAbstract = false; - shareRuntime = false; - shareTmpdir = false; - - # 0, PresetStrict - expectedFilter = { - x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735"; - aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297"; - }; - - want = { - env = [ - "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus" - "HOME=/var/lib/hakurei/u0/a1" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a1" - "WAYLAND_DISPLAY=wayland-0" - "XDG_RUNTIME_DIR=/run/user/65534" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=wayland" - "PULSE_SERVER=unix:/run/user/65534/pulse/native" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" { - core = fs "80001ff" null null; - dri = fs "800001ed" extraPaths.${system}."/dev/dri" null; - fd = fs "80001ff" null null; - full = fs "42001b6" null null; - mqueue = fs "801001ff" { } null; - null = fs "42001b6" null ""; - ptmx = fs "80001ff" null null; - pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; - random = fs "42001b6" null null; - shm = fs "801001ff" { } null; - stderr = fs "80001ff" null null; - stdin = fs "80001ff" null null; - stdout = fs "80001ff" null null; - tty = fs "42001b6" null null; - urandom = fs "42001b6" null null; - zero = fs "42001b6" null null; - } null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:65534:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a1:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a1:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - nix = fs "800001c0" { store = fs "801001fd" null null; } null; - proc = fs "8000016d" null null; - run = fs "800001ed" { - current-system = fs "80001ff" null null; - opengl-driver = fs "80001ff" null null; - user = fs "800001ed" { - "65534" = fs "800001c0" { - bus = fs "10001fd" null null; - pulse = fs "800001c0" { native = fs "10001ff" null null; } null; - wayland-0 = fs "1000038" null null; - } null; - } null; - } null; - sys = fs "800001c0" { - block = fs "800001ed" ( - { - ${extraPaths.${system}.fd} = fs "80001ff" null null; - loop0 = fs "80001ff" null null; - loop1 = fs "80001ff" null null; - loop2 = fs "80001ff" null null; - loop3 = fs "80001ff" null null; - loop4 = fs "80001ff" null null; - loop5 = fs "80001ff" null null; - loop6 = fs "80001ff" null null; - loop7 = fs "80001ff" null null; - vda = fs "80001ff" null null; - } - // extraPaths.${system}.sr - ) null; - bus = fs "800001ed" null null; - class = fs "800001ed" null null; - dev = fs "800001ed" { - block = fs "800001ed" null null; - char = fs "800001ed" null null; - } null; - devices = fs "800001ed" null null; - } null; - tmp = fs "801001ff" { } null; - usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001c0" { - tmp = fs "801001ff" null null; - lib = fs "800001c0" { - hakurei = fs "800001c0" { - u0 = fs "800001c0" { - a1 = fs "800001c0" { - ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null; - ".config" = fs "800001ed" { - "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null; - systemd = fs "800001ed" { - user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null; - } null; - } null; - ".local" = fs "800001ed" { - state = fs "800001ed" { - ".keep" = fs "80001ff" null ""; - home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null; - nix = fs "800001ed" { - profiles = fs "800001ed" { - profile = fs "80001ff" null null; - profile-1-link = fs "80001ff" null null; - } null; - } null; - } null; - } null; - ".nix-defexpr" = fs "800001ed" { - channels = fs "80001ff" null null; - channels_root = fs "80001ff" null null; - } null; - ".nix-profile" = fs "80001ff" null null; - } null; - } null; - } null; - } null; - } null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001") - (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw") - (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=10001,gid=10001") - (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/urandom" "/dev/urandom" "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/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw") - (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=16384k,mode=755,uid=10001,gid=10001") - (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=10001,gid=10001") - (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/vda" "rw") - (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = false; - socket_pathname = false; - }; -} diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix deleted file mode 100644 index 4ba9360e..00000000 --- a/test/sandbox/case/tty.nix +++ /dev/null @@ -1,288 +0,0 @@ -{ - fs, - ent, - ignore, - system, -}: -let - extraPaths = { - x86_64-linux = { - fd = "fd0"; - "/dev/dri" = { - by-path = fs "800001ed" { - "pci-0000:00:09.0-card" = fs "80001ff" null null; - "pci-0000:00:09.0-render" = fs "80001ff" null null; - } null; - card0 = fs "42001b0" null null; - renderD128 = fs "42001b6" null null; - }; - sr = { - sr0 = fs "80001ff" null null; - }; - }; - aarch64-linux = { - fd = "mtdblock0"; - "/dev/dri" = null; - sr = { }; - }; - }; -in -{ - name = "tty"; - tty = true; - device = false; - mapRealUid = false; - useCommonPaths = true; - userns = false; - x11 = true; - hostAbstract = true; - shareRuntime = true; - shareTmpdir = false; - - # 0, PresetExt | PresetDenyNS | PresetDenyDevel - expectedFilter = { - x86_64-linux = "0b76007476c1c9e25dbf674c29fdf609a1656a70063e49327654e1b5360ad3da06e1a3e32bf80e961c5516ad83d4b9e7e9bde876a93797e27627d2555c25858b"; - aarch64-linux = "cf1f4dc87436ba8ec95d268b663a6397bb0b4a5ac64d8557e6cc529d8b0f6f65dad3a92b62ed29d85eee9c6dde1267757a4d0f86032e8a45ca1bceadfa34cf5e"; - }; - - want = { - env = [ - "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus" - "DISPLAY=:0" - "HOME=/var/lib/hakurei/u0/a2" - "SHELL=/run/current-system/sw/bin/bash" - "TERM=linux" - "USER=u0_a2" - "WAYLAND_DISPLAY=wayland-0" - "XDG_RUNTIME_DIR=/run/user/65534" - "XDG_SESSION_CLASS=user" - "XDG_SESSION_TYPE=wayland" - "PULSE_SERVER=unix:/run/user/65534/pulse/native" - ]; - - fs = fs "dead" { - ".hakurei" = fs "800001ed" { - ".ro-store" = fs "801001fd" null null; - store = fs "800001ff" null null; - } null; - bin = fs "800001ed" { sh = fs "80001ff" null null; } null; - dev = fs "800001ed" { - console = fs "4200190" null null; - core = fs "80001ff" null null; - dri = fs "800001ed" extraPaths.${system}."/dev/dri" null; - fd = fs "80001ff" null null; - full = fs "42001b6" null null; - mqueue = fs "801001ff" { } null; - null = fs "42001b6" null ""; - ptmx = fs "80001ff" null null; - pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; - random = fs "42001b6" null null; - shm = fs "801001ff" { } null; - stderr = fs "80001ff" null null; - stdin = fs "80001ff" null null; - stdout = fs "80001ff" null null; - tty = fs "42001b6" null null; - urandom = fs "42001b6" null null; - zero = fs "42001b6" null null; - } null; - etc = fs "800001ed" { - ".clean" = fs "80001ff" null null; - ".host" = fs "800001c0" null null; - ".updated" = fs "80001ff" null null; - "NIXOS" = fs "80001ff" null null; - "X11" = fs "80001ff" null null; - "alsa" = fs "80001ff" null null; - "bash_logout" = fs "80001ff" null null; - "bashrc" = fs "80001ff" null null; - "binfmt.d" = fs "80001ff" null null; - "dbus-1" = fs "80001ff" null null; - "default" = fs "80001ff" null null; - "dhcpcd.exit-hook" = fs "80001ff" null null; - "environment.d" = fs "80001ff" null null; - "fonts" = fs "80001ff" null null; - "fstab" = fs "80001ff" null null; - "hsurc" = fs "80001ff" null null; - "fuse.conf" = fs "80001ff" null null; - "gai.conf" = fs "80001ff" null null; - "group" = fs "180" null "hakurei:x:65534:\n"; - "host.conf" = fs "80001ff" null null; - "hostname" = fs "80001ff" null null; - "hosts" = fs "80001ff" null null; - "inputrc" = fs "80001ff" null null; - "issue" = fs "80001ff" null null; - "kbd" = fs "80001ff" null null; - "locale.conf" = fs "80001ff" null null; - "login.defs" = fs "80001ff" null null; - "lsb-release" = fs "80001ff" null null; - "lvm" = fs "80001ff" null null; - "machine-id" = fs "80001ff" null null; - "man_db.conf" = fs "80001ff" null null; - "modprobe.d" = fs "80001ff" null null; - "modules-load.d" = fs "80001ff" null null; - "mtab" = fs "80001ff" null null; - "nanorc" = fs "80001ff" null null; - "netgroup" = fs "80001ff" null null; - "nix" = fs "80001ff" null null; - "nixos" = fs "80001ff" null null; - "nscd.conf" = fs "80001ff" null null; - "nsswitch.conf" = fs "80001ff" null null; - "os-release" = fs "80001ff" null null; - "pam" = fs "80001ff" null null; - "pam.d" = fs "80001ff" null null; - "passwd" = fs "180" null "u0_a2:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a2:/run/current-system/sw/bin/bash\n"; - "pipewire" = fs "80001ff" null null; - "pki" = fs "80001ff" null null; - "polkit-1" = fs "80001ff" null null; - "profile" = fs "80001ff" null null; - "protocols" = fs "80001ff" null null; - "resolv.conf" = fs "80001ff" null null; - "resolvconf.conf" = fs "80001ff" null null; - "rpc" = fs "80001ff" null null; - "services" = fs "80001ff" null null; - "set-environment" = fs "80001ff" null null; - "shadow" = fs "80001ff" null null; - "shells" = fs "80001ff" null null; - "speech-dispatcher" = fs "80001ff" null null; - "ssh" = fs "80001ff" null null; - "ssl" = fs "80001ff" null null; - "static" = fs "80001ff" null null; - "subgid" = fs "80001ff" null null; - "subuid" = fs "80001ff" null null; - "sudoers" = fs "80001ff" null null; - "sway" = fs "80001ff" null null; - "sysctl.d" = fs "80001ff" null null; - "systemd" = fs "80001ff" null null; - "terminfo" = fs "80001ff" null null; - "tmpfiles.d" = fs "80001ff" null null; - "udev" = fs "80001ff" null null; - "vconsole.conf" = fs "80001ff" null null; - "xdg" = fs "80001ff" null null; - "zoneinfo" = fs "80001ff" null null; - } null; - nix = fs "800001c0" { store = fs "801001fd" null null; } null; - proc = fs "8000016d" null null; - run = fs "800001ed" { - current-system = fs "80001ff" null null; - opengl-driver = fs "80001ff" null null; - user = fs "800001ed" { - "65534" = fs "800001f8" { - bus = fs "10001fd" null null; - pulse = fs "800001c0" { native = fs "10001ff" null null; } null; - wayland-0 = fs "1000038" null null; - } null; - } null; - } null; - sys = fs "800001c0" { - block = fs "800001ed" ( - { - ${extraPaths.${system}.fd} = fs "80001ff" null null; - loop0 = fs "80001ff" null null; - loop1 = fs "80001ff" null null; - loop2 = fs "80001ff" null null; - loop3 = fs "80001ff" null null; - loop4 = fs "80001ff" null null; - loop5 = fs "80001ff" null null; - loop6 = fs "80001ff" null null; - loop7 = fs "80001ff" null null; - vda = fs "80001ff" null null; - } - // extraPaths.${system}.sr - ) null; - bus = fs "800001ed" null null; - class = fs "800001ed" null null; - dev = fs "800001ed" { - block = fs "800001ed" null null; - char = fs "800001ed" null null; - } null; - devices = fs "800001ed" null null; - } null; - tmp = fs "801001ff" { - ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null; - } null; - usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null; - var = fs "800001c0" { - tmp = fs "801001ff" null null; - lib = fs "800001c0" { - hakurei = fs "800001c0" { - u0 = fs "800001c0" { - a2 = fs "800001c0" { - ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null; - ".config" = fs "800001ed" { - "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null; - systemd = fs "800001ed" { - user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null; - } null; - } null; - ".local" = fs "800001ed" { - state = fs "800001ed" { - ".keep" = fs "80001ff" null ""; - home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null; - nix = fs "800001ed" { - profiles = fs "800001ed" { - profile = fs "80001ff" null null; - profile-1-link = fs "80001ff" null null; - } null; - } null; - } null; - } null; - ".nix-defexpr" = fs "800001ed" { - channels = fs "80001ff" null null; - channels_root = fs "80001ff" null null; - } null; - ".nix-profile" = fs "80001ff" null null; - } null; - } null; - } null; - } null; - cache = fs "800001ed" { private = fs "800001c0" null null; } null; - } null; - } null; - - mount = [ - (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002") - (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw") - (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=10002,gid=10002") - (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/urandom" "/dev/urandom" "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 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/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002") - (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10002,gid=10002") - (ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (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=10002,gid=10002") - (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/vda" "rw") - (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on") - (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw") - (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) - (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr") - (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,uuid=on,userxattr") - (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw") - ]; - - seccomp = true; - - try_socket = "/tmp/.X11-unix/X0"; - socket_abstract = true; - socket_pathname = true; - }; -} diff --git a/test/sandbox/configuration.nix b/test/sandbox/configuration.nix deleted file mode 100644 index bc189f7d..00000000 --- a/test/sandbox/configuration.nix +++ /dev/null @@ -1,113 +0,0 @@ -{ - lib, - pkgs, - config, - ... -}: -let - testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.hakurei.package) version; }; - testCases = import ./case pkgs.stdenv.hostPlatform.system lib testProgram; -in -{ - users.users = { - alice = { - isNormalUser = true; - description = "Alice Foobar"; - password = "foobar"; - uid = 1000; - }; - }; - - home-manager.users.alice.home.stateVersion = "24.11"; - - # Automatically login on tty1 as a normal user: - services.getty.autologinUser = "alice"; - - environment = { - systemPackages = [ - # For checking seccomp outcome: - testProgram - - # For checking pd outcome: - (pkgs.writeShellScriptBin "check-sandbox-pd" '' - hakurei -v exec hakurei-test \ - -p "/var/tmp/.hakurei-check-ok.0" \ - -t ${toString (builtins.toFile "hakurei-pd-want.json" (builtins.toJSON testCases.pd.want))} \ - -s ${testCases.pd.expectedFilter.${pkgs.stdenv.hostPlatform.system}} "$@" - '') - ]; - - variables = { - SWAYSOCK = "/tmp/sway-ipc.sock"; - WLR_RENDERER = "pixman"; - }; - }; - - # Automatically configure and start Sway when logging in on tty1: - programs.bash.loginShellInit = '' - if [ "$(tty)" = "/dev/tty1" ]; then - set -e - - mkdir -p ~/.config/sway - (sed s/Mod4/Mod1/ /etc/sway/config && - echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill' && - echo 'output Virtual-1 res 1680x1050') > ~/.config/sway/config - - sway --validate - systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok - fi - ''; - - programs.sway.enable = true; - - virtualisation.qemu.options = [ - # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch: - "-vga none -device virtio-gpu-pci" - - # Increase performance: - "-smp 8" - ]; - - environment.hakurei = { - enable = true; - stateDir = "/var/lib/hakurei"; - users.alice = 0; - - extraHomeConfig = { - home.stateVersion = "23.05"; - }; - - commonPaths = [ - { - type = "bind"; - src = "/var/tmp"; - write = true; - } - { - type = "bind"; - src = "/var/cache"; - write = true; - } - { - type = "overlay"; - dst = "/.hakurei/.ro-store"; - lower = [ - "/nix/.ro-store" - "/nix/.rw-store/upper" - ]; - } - { - type = "overlay"; - dst = "/.hakurei/store"; - lower = [ - "/nix/.ro-store" - "/nix/.rw-store/upper" - ]; - upper = "/tmp/.hakurei-store-rw/upper"; - work = "/tmp/.hakurei-store-rw/work"; - } - ]; - - inherit (testCases) apps; - }; -} diff --git a/test/sandbox/default.nix b/test/sandbox/default.nix deleted file mode 100644 index 47a59de9..00000000 --- a/test/sandbox/default.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ - lib, - testers, - - self, - withRace ? false, -}: - -testers.nixosTest { - name = "hakurei-sandbox" + (if withRace then "-race" else ""); - nodes.machine = - { options, pkgs, ... }: - { - # Run with Go race detector: - environment.hakurei = lib.mkIf withRace rec { - # race detector does not support static linking - package = (pkgs.callPackage ../package.nix { }).overrideAttrs (previousAttrs: { - env = previousAttrs.env // { - GOFLAGS = previousAttrs.env.GOFLAGS + " -race"; - }; - }); - hsuPackage = options.environment.hakurei.hsuPackage.default.override { hakurei = package; }; - }; - - imports = [ - ./configuration.nix - - self.nixosModules.hakurei - self.inputs.home-manager.nixosModules.home-manager - ]; - }; - - # adapted from nixos sway integration tests - - # testScriptWithTypes:49: error: Cannot call function of unknown type - # (machine.succeed if succeed else machine.execute)( - # ^ - # Found 1 error in 1 file (checked 1 source file) - skipTypeCheck = true; - testScript = builtins.readFile ./test.py; -} diff --git a/test/sandbox/test.py b/test/sandbox/test.py deleted file mode 100644 index a431daab..00000000 --- a/test/sandbox/test.py +++ /dev/null @@ -1,88 +0,0 @@ -import json -import shlex - -q = shlex.quote - - -def swaymsg(command: str = "", succeed=True, type="command"): - assert command != "" or type != "command", "Must specify command or type" - shell = q(f"swaymsg -t {q(type)} -- {q(command)}") - with machine.nested( - f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed) - ): - ret = (machine.succeed if succeed else machine.execute)( - f"su - alice -c {shell}" - ) - - # execute also returns a status code, but disregard. - if not succeed: - _, ret = ret - - if not succeed and not ret: - return None - - parsed = json.loads(ret) - return parsed - - -def check_filter(check_offset, name, pname): - pid = int(machine.wait_until_succeeds(f"pgrep -U {10000+check_offset} -x {pname}")) - 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}")) - - -start_all() -machine.wait_for_unit("multi-user.target") - -# To check hakurei's version: -print(machine.succeed("sudo -u alice -i hakurei version")) - -# Wait for Sway to complete startup: -machine.wait_for_file("/run/user/1000/wayland-1") -machine.wait_for_file("/tmp/sway-ipc.sock") - -# Check pd seccomp outcome: -swaymsg("exec hakurei exec cat") -check_filter(0, "pdlike", "cat") - -# Check fd leak: -swaymsg("exec exec 127</proc/cmdline && hakurei -v exec sleep infinity") -pd_identity0_sleep_pid = int(machine.wait_until_succeeds("pgrep -U 10000 -x sleep")) -print(machine.succeed(f"hakurei-test fd {pd_identity0_sleep_pid}")) -machine.succeed(f"kill -INT {pd_identity0_sleep_pid}") - -# Verify capabilities/securebits in user namespace: -print(machine.succeed("sudo -u alice -i hakurei exec capsh --print")) -print(machine.succeed("sudo -u alice -i hakurei exec capsh --has-no-new-privs")) -print(machine.fail("sudo -u alice -i hakurei exec capsh --has-a=CAP_SYS_ADMIN")) -print(machine.fail("sudo -u alice -i hakurei exec capsh --has-b=CAP_SYS_ADMIN")) -print(machine.fail("sudo -u alice -i hakurei exec capsh --has-i=CAP_SYS_ADMIN")) -print(machine.fail("sudo -u alice -i hakurei exec capsh --has-p=CAP_SYS_ADMIN")) -print(machine.fail("sudo -u alice -i hakurei exec umount -R /dev")) - -# Check sandbox outcome: -machine.succeed("install -dm0777 /tmp/.hakurei-store-rw/{upper,work}") -check_offset = 0 -def check_sandbox(name): - global check_offset - swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}") - machine.wait_for_file(f"/var/tmp/.hakurei-check-ok.{check_offset}") - check_filter(check_offset, name, "hakurei-test") - check_offset += 1 - - -check_sandbox("pd") -check_sandbox("preset") -check_sandbox("tty") -check_sandbox("mapuid") -check_sandbox("device") -check_sandbox("pdlike") - -# Exit Sway and verify process exit status 0: -machine.wait_until_fails("pgrep -x hakurei") -swaymsg("exit", succeed=False) -machine.wait_for_file("/tmp/sway-exit-ok") - -# Print hakurei runDir contents: -print(machine.fail("ls /run/user/1000/hakurei")) -machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +") diff --git a/test/sandbox/tool/main.go b/test/sandbox/tool/main.go deleted file mode 100644 index 889142d4..00000000 --- a/test/sandbox/tool/main.go +++ /dev/null @@ -1,106 +0,0 @@ -//go:build testtool - -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/signal" - "strconv" - "strings" - "syscall" - - "hakurei.app/test/internal/sandbox" -) - -var ( - flagMarkerPath string - flagTestCase string - flagBpfHash string -) - -func init() { - flag.StringVar(&flagMarkerPath, "p", "/tmp/sandbox-ok", "Pathname of completion marker") - flag.StringVar(&flagTestCase, "t", "", "Nix store path to test case file") - flag.StringVar(&flagBpfHash, "s", "", "String representation of expected bpf sha512 hash") -} - -func main() { - log.SetFlags(0) - log.SetPrefix("test: ") - flag.Parse() - - args := flag.Args() - if len(args) < 1 { - s := make(chan os.Signal, 1) - signal.Notify(s, syscall.SIGINT) - go func() { <-s; log.Println("exiting on signal (likely from verifier)"); os.Exit(0) }() - - (&sandbox.T{FS: os.DirFS("/")}).MustCheckFile(flagTestCase) - if _, err := os.Create(flagMarkerPath); err != nil { - log.Fatalf("cannot create success marker: %v", err) - } - log.Printf("blocking for seccomp check (%s)", flagMarkerPath) - select {} - return - } - - switch args[0] { - case "filter": - if len(args) != 2 { - log.Fatal("invalid argument") - } - - if pid, err := strconv.Atoi(strings.TrimSpace(args[1])); err != nil { - log.Fatalf("%s", err) - } else if pid < 1 { - log.Fatalf("%d out of range", pid) - } else { - sandbox.MustCheckFilter(pid, flagBpfHash) - if err = syscall.Kill(pid, syscall.SIGINT); err != nil { - log.Fatalf("cannot signal check process: %v", err) - } - } - - case "hash": // this eases the pain of passing the hash to python - fmt.Print(flagBpfHash) - - case "fd": - if len(args) != 2 { - log.Fatal("invalid argument") - } - prefix := fmt.Sprintf("/proc/%s/fd/", args[1]) - - var fail bool - if entries, err := os.ReadDir(prefix); err != nil { - log.Fatal(err.Error()) - } else { - for _, ent := range entries { - var fd int - if fd, err = strconv.Atoi(ent.Name()); err != nil { - log.Fatal(err.Error()) - } - - // skip standard streams - if fd <= 2 { - continue - } - fail = true - - var d string - if d, err = os.Readlink(prefix + ent.Name()); err != nil { - log.Fatal(err.Error()) - } - log.Printf("[FAIL] extra fd %d -> %s", fd, d) - } - } - if fail { - log.Fatal("[FAIL] file descriptors leaked") - } - - default: - log.Fatal("invalid argument") - } -} diff --git a/test/sandbox/tool/package.nix b/test/sandbox/tool/package.nix deleted file mode 100644 index 13e18272..00000000 --- a/test/sandbox/tool/package.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - lib, - buildGoModule, - pkg-config, - util-linux, - - version, -}: -buildGoModule rec { - pname = "check-sandbox"; - inherit version; - - src = builtins.path { - name = "${pname}-src"; - path = lib.cleanSource ../../.; - filter = path: type: (type == "directory") || (type == "regular" && lib.hasSuffix ".go" path); - }; - vendorHash = null; - - tags = [ "testtool" ]; - - buildInputs = [ util-linux ]; - nativeBuildInputs = [ pkg-config ]; - - preBuild = '' - go mod init hakurei.app/test >& /dev/null - ''; - - postInstall = '' - mv $out/bin/tool $out/bin/hakurei-test - ''; -} diff --git a/test/sharefs/configuration.nix b/test/sharefs/configuration.nix deleted file mode 100644 index 05d67dcb..00000000 --- a/test/sharefs/configuration.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ pkgs, ... }: -{ - users.users = { - alice = { - isNormalUser = true; - description = "Alice Foobar"; - password = "foobar"; - uid = 1000; - }; - }; - - home-manager.users.alice.home.stateVersion = "24.11"; - - # Automatically login on tty1 as a normal user: - services.getty.autologinUser = "alice"; - - environment = { - # For benchmarking sharefs: - systemPackages = [ pkgs.fsmark ]; - }; - - virtualisation = { - # Hopefully reduces spurious test failures: - memorySize = if pkgs.stdenv.hostPlatform.is32bit then 2046 else 8192; - - diskSize = 6 * 1024; - - qemu.options = [ - # Increase test performance: - "-smp 16" - ]; - }; - - environment.hakurei = rec { - enable = true; - stateDir = "/var/lib/hakurei"; - sharefs.source = "${stateDir}/sdcard"; - users.alice = 0; - - extraHomeConfig = { - home.stateVersion = "23.05"; - }; - }; -} diff --git a/test/sharefs/default.nix b/test/sharefs/default.nix deleted file mode 100644 index e963eaa6..00000000 --- a/test/sharefs/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -{ - testers, - - system, - self, -}: -testers.nixosTest { - name = "sharefs"; - nodes.machine = - { options, pkgs, ... }: - let - fhs = - let - hakurei = options.environment.hakurei.package.default; - in - pkgs.buildFHSEnv { - pname = "hakurei-fhs"; - inherit (hakurei) version; - targetPkgs = _: hakurei.targetPkgs; - extraOutputsToInstall = [ "dev" ]; - profile = '' - export PKG_CONFIG_PATH="/usr/share/pkgconfig:$PKG_CONFIG_PATH" - ''; - }; - in - { - environment.systemPackages = [ - # For go tests: - (pkgs.writeShellScriptBin "sharefs-workload-hakurei-tests" '' - cp -r "${self.packages.${system}.hakurei.src}" "/sdcard/hakurei" && cd "/sdcard/hakurei" - ${fhs}/bin/hakurei-fhs -c 'ROSA_SKIP_BINFMT=1 CC="clang -O3 -Werror" go test ./...' - '') - ]; - - imports = [ - ./configuration.nix - - self.nixosModules.hakurei - self.inputs.home-manager.nixosModules.home-manager - ]; - }; - - testScript = builtins.readFile ./test.py; -} diff --git a/test/sharefs/raceattr.go b/test/sharefs/raceattr.go deleted file mode 100644 index 412cb2b3..00000000 --- a/test/sharefs/raceattr.go +++ /dev/null @@ -1,122 +0,0 @@ -//go:build raceattr - -// The raceattr program reproduces vfs inode file attribute race. -// -// Even though libfuse high-level API presents the address of a struct stat -// alongside struct fuse_context, file attributes are actually inherent to the -// inode, instead of the specific call from userspace. The kernel implementation -// in fs/fuse/xattr.c appears to make stale data in the inode (set by a previous -// call) impossible or very unlikely to reach userspace via the stat family of -// syscalls. However, when using default_permissions to have the VFS check -// permissions, this race still happens, despite the resulting struct stat being -// correct when overriding the check via capabilities otherwise. -// -// This program reproduces the failure, but because of its continuous nature, it -// is provided independent of the vm integration test suite. -package main - -import ( - "context" - "flag" - "log" - "os" - "os/signal" - "runtime" - "sync" - "sync/atomic" - "syscall" -) - -func newStatAs( - ctx context.Context, cancel context.CancelFunc, - n *atomic.Uint64, ok *atomic.Bool, - uid uint32, pathname string, - continuous bool, -) func() { - return func() { - runtime.LockOSThread() - defer cancel() - - if _, _, errno := syscall.Syscall( - syscall.SYS_SETUID, uintptr(uid), - 0, 0, - ); errno != 0 { - cancel() - log.Printf("cannot set uid to %d: %s", uid, errno) - } - - var stat syscall.Stat_t - for { - if ctx.Err() != nil { - return - } - - if err := syscall.Lstat(pathname, &stat); err != nil { - // SHAREFS_PERM_DIR not world executable, or - // SHAREFS_PERM_REG not world readable - if !continuous { - cancel() - } - ok.Store(true) - log.Printf("uid %d: %v", uid, err) - } else if stat.Uid != uid { - // appears to be unreachable - if !continuous { - cancel() - } - ok.Store(true) - log.Printf("got uid %d instead of %d", stat.Uid, uid) - } - n.Add(1) - } - } -} - -func main() { - log.SetFlags(0) - log.SetPrefix("raceattr: ") - - p := flag.String("target", "/sdcard/raceattr", "pathname of test file") - u0 := flag.Int("uid0", 1<<10-1, "first uid") - u1 := flag.Int("uid1", 1<<10-2, "second uid") - count := flag.Int("count", 1, "threads per uid") - continuous := flag.Bool("continuous", false, "keep running even after reproduce") - flag.Parse() - - if os.Geteuid() != 0 { - log.Fatal("this program must run as root") - } - - ctx, cancel := signal.NotifyContext( - context.Background(), - syscall.SIGINT, - syscall.SIGTERM, - syscall.SIGHUP, - ) - - if err := os.WriteFile(*p, nil, 0); err != nil { - log.Fatal(err) - } - - var ( - wg sync.WaitGroup - - n atomic.Uint64 - ok atomic.Bool - ) - - if *count < 1 { - *count = 1 - } - for range *count { - wg.Go(newStatAs(ctx, cancel, &n, &ok, uint32(*u0), *p, *continuous)) - if *u1 >= 0 { - wg.Go(newStatAs(ctx, cancel, &n, &ok, uint32(*u1), *p, *continuous)) - } - } - - wg.Wait() - if !*continuous && ok.Load() { - log.Printf("reproduced after %d calls", n.Load()) - } -} diff --git a/test/sharefs/test.py b/test/sharefs/test.py deleted file mode 100644 index 4b925c9c..00000000 --- a/test/sharefs/test.py +++ /dev/null @@ -1,60 +0,0 @@ -start_all() -machine.wait_for_unit("multi-user.target") - -# To check sharefs version: -print(machine.succeed("sharefs -V")) - -# Make sure sharefs started: -machine.wait_for_unit("sdcard.mount") - -machine.succeed("mkdir /mnt") -def check_bad_opts_output(opts, want, source="/etc", privileged=False): - output = machine.fail(("" if privileged else "sudo -u alice -i ") + f"sharefs -f -o source={source},{opts} /mnt 2>&1") - if output != want: - raise Exception(f"unexpected output: {output}") - -# Malformed setuid/setgid representation: -check_bad_opts_output("setuid=ff", "sharefs: invalid value for option setuid\n") -check_bad_opts_output("setgid=ff", "sharefs: invalid value for option setgid\n") - -# Bounds check for setuid/setgid: -check_bad_opts_output("setuid=0", "sharefs: invalid value for option setuid\n") -check_bad_opts_output("setgid=0", "sharefs: invalid value for option setgid\n") -check_bad_opts_output("setuid=-1", "sharefs: invalid value for option setuid\n") -check_bad_opts_output("setgid=-1", "sharefs: invalid value for option setgid\n") - -# Non-root setuid/setgid: -check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n") -check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n") -check_bad_opts_output("setuid=1023,setgid=1023", "sharefs: setuid and setgid has no effect when not starting as root\n") -check_bad_opts_output("mkdir", "sharefs: mkdir has no effect when not starting as root\n") - -# Starting as root without setuid/setgid: -check_bad_opts_output("allow_other", "sharefs: setuid and setgid must not be 0\n", privileged=True) -check_bad_opts_output("setuid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True) -check_bad_opts_output("setgid=1023", "sharefs: setuid and setgid must not be 0\n", privileged=True) - -# Make sure nothing actually got mounted: -machine.fail("umount /mnt") -machine.succeed("rmdir /mnt") - -# Unprivileged mount/unmount: -machine.succeed("sudo -u alice -i mkdir /home/alice/{sdcard,persistent}") -machine.succeed("sudo -u alice -i sharefs -o source=/home/alice/persistent /home/alice/sdcard") -machine.succeed("sudo -u alice -i touch /home/alice/sdcard/check") -machine.succeed("sudo -u alice -i umount /home/alice/sdcard") -machine.succeed("sudo -u alice -i rm /home/alice/persistent/check") -machine.succeed("sudo -u alice -i rmdir /home/alice/{sdcard,persistent}") - -# Benchmark sharefs: -machine.succeed("fs_mark -v -d /sdcard/fs_mark -l /tmp/fs_log.txt") -machine.copy_from_vm("/tmp/fs_log.txt", "") - -# Check permissions: -machine.succeed("sudo -u sharefs touch /var/lib/hakurei/sdcard/fs_mark/.check") -machine.succeed("sudo -u sharefs rm /var/lib/hakurei/sdcard/fs_mark/.check") -machine.succeed("sudo -u alice rm -rf /sdcard/fs_mark") -machine.fail("ls /var/lib/hakurei/sdcard/fs_mark") - -# Run hakurei tests on sharefs: -machine.succeed("sudo -u alice -i sharefs-workload-hakurei-tests") diff --git a/test/test.py b/test/test.py deleted file mode 100644 index 98f08275..00000000 --- a/test/test.py +++ /dev/null @@ -1,315 +0,0 @@ -import json -import shlex - -q = shlex.quote -NODE_GROUPS = ["nodes", "floating_nodes"] - - -def swaymsg(command: str = "", succeed=True, type="command"): - assert command != "" or type != "command", "Must specify command or type" - shell = q(f"swaymsg -t {q(type)} -- {q(command)}") - with machine.nested(f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed)): - ret = (machine.succeed if succeed else machine.execute)( - f"su - alice -c {shell}" - ) - - # execute also returns a status code, but disregard. - if not succeed: - _, ret = ret - - if not succeed and not ret: - return None - - parsed = json.loads(ret) - return parsed - - -def walk(tree): - yield tree - for group in NODE_GROUPS: - for node in tree.get(group, []): - yield from walk(node) - - -def wait_for_window(pattern): - def func(last_chance): - nodes = (node["name"] for node in walk(swaymsg(type="get_tree"))) - - if last_chance: - nodes = list(nodes) - machine.log(f"Last call! Current list of windows: {nodes}") - - return any(pattern in name for name in nodes) - - retry(func) - - -def collect_state_ui(name): - swaymsg(f"exec hakurei ps > '/tmp/{name}.ps'") - machine.wait_for_file(f"/tmp/{name}.ps") - machine.copy_from_vm(f"/tmp/{name}.ps", "") - swaymsg(f"exec hakurei --json ps > '/tmp/{name}.json'") - machine.wait_for_file(f"/tmp/{name}.json") - machine.copy_from_vm(f"/tmp/{name}.json", "") - machine.screenshot(name) - - -def check_state(name, enablements): - instances = json.loads(machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei --json ps")) - if len(instances) != 1: - raise Exception(f"unexpected state length {len(instances)}") - instance = instances[0] - - command = f"{name}-start" - if not (instance['container']['path'].startswith("/nix/store/")) or not (instance['container']['path'].endswith(command)): - raise Exception(f"unexpected path {instance['path']}") - - if len(instance['container']['args']) != 1 or instance['container']['args'][0] != command: - raise Exception(f"unexpected args {instance['args']}") - - if instance['enablements'] != enablements: - raise Exception(f"unexpected enablements {instance['enablements']['enablements']}") - - -def hakurei(command): - swaymsg(f"exec hakurei {command}") - - -start_all() -machine.wait_for_unit("multi-user.target") - -# To check hakurei's version: -print(machine.succeed("sudo -u alice -i hakurei version")) - -# Wait for Sway to complete startup: -machine.wait_for_file("/run/user/1000/wayland-1") -machine.wait_for_file("/tmp/sway-ipc.sock") - -# Run hakurei Go tests outside of nix build in the background: -swaymsg("exec hakurei-test") - -# Deny unmapped uid: -denyOutput = machine.fail("sudo -u untrusted -i hakurei exec &>/dev/stdout") -print(denyOutput) -denyOutputVerbose = machine.fail("sudo -u untrusted -i hakurei -v exec &>/dev/stdout") -print(denyOutputVerbose) - -# Direct hsu call: -userid = machine.succeed("sudo -u alice -i hsu") -if userid != "0": - raise Exception(f"unexpected userid: {userid}") - -# Verify hsu fault behaviour: -if denyOutput != "hsu: uid 1001 is not in the hsurc file\n": - raise Exception(f"unexpected deny output:\n{denyOutput}") -if denyOutputVerbose != "hsu: uid 1001 is not in the hsurc file\nhakurei: *cannot retrieve user id from setuid wrapper: current user is not in the hsurc file\n": - raise Exception(f"unexpected deny verbose output:\n{denyOutputVerbose}") - -# Verify timeout behaviour: -machine.succeed('sudo -u alice -i hakurei-check-linger-timeout > /var/tmp/linger-stdout 2> /var/tmp/linger-stderr || (cat /var/tmp/linger-stderr; false)') -linger_stdout = machine.succeed("cat /var/tmp/linger-stdout") -linger_stderr = machine.succeed("cat /var/tmp/linger-stderr") -if linger_stdout != "": - raise Exception(f"unexpected stdout: {linger_stdout}") -if linger_stderr != "init: timeout exceeded waiting for lingering processes\n": - raise Exception(f"unexpected stderr: {linger_stderr}") - -check_offset = 0 - - -def hakurei_identity(offset): - return 1+check_offset+offset - - -# Start hakurei permissive defaults outside Wayland session: -print(machine.succeed("sudo -u alice -i hakurei -v exec -a 0 touch /tmp/pd-bare-ok")) -machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-bare-ok") - -# Verify silent output permissive defaults: -output = machine.succeed("sudo -u alice -i hakurei exec -a 0 true &>/dev/stdout") -if output != "": - raise Exception(f"unexpected output\n{output}") - -# Verify silent output permissive defaults signal: -def silent_output_interrupt(flags): - swaymsg("exec foot") - wait_for_window("alice@machine") - # identity 0 does not have home-manager - machine.send_chars(f"exec hakurei exec {flags}-a 0 sh -c 'export PATH=/run/current-system/sw/bin:$PATH && touch /tmp/pd-silent-ready && sleep infinity' &>/tmp/pd-silent\n") - machine.wait_for_file("/tmp/hakurei.0/tmpdir/0/pd-silent-ready") - machine.succeed("rm /tmp/hakurei.0/tmpdir/0/pd-silent-ready") - machine.send_key("ctrl-c") - machine.wait_until_fails("pgrep foot") - machine.wait_until_fails(f"pgrep -u alice -f 'hakurei exec {flags}-a 0 '") - output = machine.succeed("cat /tmp/pd-silent && rm /tmp/pd-silent") - if output != "": - raise Exception(f"unexpected output\n{output}") - - -silent_output_interrupt("") -silent_output_interrupt("--dbus ") # this one is especially painful as it maintains a helper -silent_output_interrupt("--wayland -X --dbus --pulse ") - -# Verify graceful failure on bad Wayland display name: -print(machine.fail("sudo -u alice -i hakurei -v exec --wayland true")) - -# Start hakurei permissive defaults within Wayland session: -hakurei('-v exec --wayland --dbus --dbus-log notify-send -a "NixOS Tests" "Test notification" "Notification from within sandbox." && touch /tmp/dbus-ok') -machine.wait_for_file("/tmp/dbus-ok") -collect_state_ui("dbus_notify_exited") -# not in pid namespace, verify termination -machine.wait_until_fails("pgrep xdg-dbus-proxy") -machine.succeed("pkill -9 mako") - -# Check revert type selection: -hakurei("-v exec --wayland -X --dbus --pulse -u p0 foot && touch /tmp/p0-exit-ok") -wait_for_window("p0@machine") -print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000")) -hakurei("-v exec --wayland -X --dbus --pulse -u p1 foot && touch /tmp/p1-exit-ok") -wait_for_window("p1@machine") -print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000")) -machine.send_chars("exit\n") -machine.wait_for_file("/tmp/p1-exit-ok") -# Verify acl is kept alive: -print(machine.succeed("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000")) -machine.send_chars("exit\n") -machine.wait_for_file("/tmp/p0-exit-ok") -machine.fail("getfacl --absolute-names --omit-header --numeric /tmp/hakurei.0/runtime | grep 10000") - -# Check invalid identifier fd behaviour: -machine.fail('echo \'{"container":{"shell":"/proc/nonexistent","home":"/proc/nonexistent","path":"/proc/nonexistent"}}\' | sudo -u alice -i hakurei -v run --identifier-fd 32767 - 2>&1 | tee > /tmp/invalid-identifier-fd') -machine.wait_for_file("/tmp/invalid-identifier-fd") -print(machine.succeed('grep "^hakurei: cannot write identifier: bad file descriptor$" /tmp/invalid-identifier-fd')) - -# Check interrupt shim behaviour: -swaymsg("exec sh -c 'ne-foot; echo -n $? > /tmp/monitor-exit-code'") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.succeed("pkill -INT -f 'hakurei -v run '") -machine.wait_until_fails("pgrep foot") -machine.wait_for_file("/tmp/monitor-exit-code") -interrupt_exit_code = int(machine.succeed("cat /tmp/monitor-exit-code")) -if interrupt_exit_code != 230: - raise Exception(f"unexpected exit code {interrupt_exit_code}") - -# Check interrupt shim behaviour immediate termination: -swaymsg("exec sh -c 'ne-foot-immediate; echo -n $? > /tmp/monitor-exit-code'") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.succeed("pkill -INT -f 'hakurei -v run '") -machine.wait_until_fails("pgrep foot") -machine.wait_for_file("/tmp/monitor-exit-code") -interrupt_exit_code = int(machine.succeed("cat /tmp/monitor-exit-code")) -if interrupt_exit_code != 254: - raise Exception(f"unexpected exit code {interrupt_exit_code}") - -# Check shim SIGCONT from unexpected process behaviour: -swaymsg("exec sh -c 'ne-foot &> /tmp/shim-cont-unexpected-pid'") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.succeed("pkill -CONT -f 'hakurei shim'") -machine.succeed("pkill -INT -f 'hakurei -v run '") -machine.wait_until_fails("pgrep foot") -machine.wait_for_file("/tmp/shim-cont-unexpected-pid") -print(machine.succeed('grep "shim: got SIGCONT from unexpected process$" /tmp/shim-cont-unexpected-pid')) - -# Check setscheduler: -sched_unset = int(machine.succeed("sudo -u alice -i hakurei -v exec cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) -if sched_unset != 0: - raise Exception(f"unexpected unset policy: {sched_unset}") -sched_idle = int(machine.succeed("sudo -u alice -i hakurei -v exec --policy=idle cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) -if sched_idle != 5: - raise Exception(f"unexpected idle policy: {sched_idle}") -sched_rr = int(machine.succeed("sudo -u alice -i hakurei -v exec --policy=rr cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) -if sched_rr != 2: - raise Exception(f"unexpected round-robin policy: {sched_idle}") - -# Start app (foot) with Wayland enablement: -swaymsg("exec ne-foot") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.send_chars("clear; wayland-info && touch /var/tmp/client-ok\n") -machine.wait_for_file("/var/tmp/client-ok") -collect_state_ui("foot_wayland") -check_state("ne-foot", {"wayland": True}) -# Verify lack of acl on XDG_RUNTIME_DIR: -machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}") -machine.send_chars("exit\n") -machine.wait_until_fails("pgrep foot") -machine.fail(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(0) + 10000}") - -# Test pipewire-pulse: -swaymsg("exec pa-foot") -wait_for_window(f"u0_a{hakurei_identity(1)}@machine") -machine.send_chars("clear; pactl info && touch /var/tmp/pulse-ok\n") -machine.wait_for_file("/var/tmp/pulse-ok") -collect_state_ui("pulse_wayland") -check_state("pa-foot", {"wayland": True, "pipewire": True}) -machine.fail("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +") -machine.send_chars("exit\n") -machine.wait_until_fails("pgrep foot") -machine.wait_until_fails("pgrep -x hakurei") -machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +") -# Test PipeWire SecurityContext: -machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pulse pactl info") -machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pulse pactl set-sink-mute @DEFAULT_SINK@ toggle") -# Test PipeWire direct access: -machine.succeed("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 pw-dump") -machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 hakurei -v exec --pipewire pw-dump") - -# Test XWayland (foot does not support X): -swaymsg("exec x11-alacritty") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.send_chars("clear; glinfo && touch /var/tmp/x11-ok\n") -machine.wait_for_file("/var/tmp/x11-ok") -collect_state_ui("alacritty_x11") -check_state("x11-alacritty", {"x11": True}) -machine.send_chars("exit\n") -machine.wait_until_fails("pgrep alacritty") - -# Start app (foot) with direct Wayland access: -swaymsg("exec da-foot") -wait_for_window(f"u0_a{hakurei_identity(3)}@machine") -machine.send_chars("clear; wayland-info && touch /var/tmp/direct-ok\n") -collect_state_ui("foot_direct") -machine.wait_for_file("/var/tmp/direct-ok") -check_state("da-foot", {"wayland": True}) -# Verify acl on XDG_RUNTIME_DIR: -print(machine.succeed(f"getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep {hakurei_identity(3) + 10000}")) -machine.send_chars("exit\n") -machine.wait_until_fails("pgrep foot") -# 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) + 10000}") - -# Test syscall filter: -print(machine.fail("sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 strace-failure")) - -# Start app (foot) with Wayland enablement from a terminal: -swaymsg("exec foot $SHELL -c '(ne-foot) & disown && exec $SHELL'") -wait_for_window(f"u0_a{hakurei_identity(0)}@machine") -machine.send_chars("clear; wayland-info && touch /var/tmp/term-ok\n") -machine.wait_for_file("/var/tmp/term-ok") -machine.send_key("alt-h") -machine.send_chars("clear; hakurei show $(hakurei ps --short) && touch /tmp/ps-show-ok && exec cat\n") -machine.wait_for_file("/tmp/ps-show-ok") -collect_state_ui("foot_wayland_term") -check_state("ne-foot", {"wayland": True}) -machine.send_key("alt-l") -machine.send_chars("exit\n") -wait_for_window("alice@machine") -machine.send_key("ctrl-c") -machine.wait_until_fails("pgrep foot") - -# Exit Sway and verify process exit status 0: -machine.wait_until_fails("pgrep -x hakurei") -swaymsg("exit", succeed=False) -machine.wait_for_file("/tmp/sway-exit-ok") - -# Print hakurei share and rundir contents: -print(machine.succeed("find /tmp/hakurei.0 " - + "-path '/tmp/hakurei.0/runtime/*/*' -prune -o " - + "-path '/tmp/hakurei.0/tmpdir/*/*' -prune -o " - + "-print")) -print(machine.succeed("find /run/user/1000/hakurei")) -machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +") - -# Verify go test status: -machine.wait_for_file("/tmp/hakurei-test-done") -print(machine.succeed("cat /tmp/hakurei-test.log")) -machine.wait_for_file("/tmp/hakurei-test-ok") |
