From e7188e211a5a2ac0ba34635a846569560bb5f000 Mon Sep 17 00:00:00 2001 From: Alois Wohlschlager Date: Mon, 1 Jul 2024 09:18:01 +0200 Subject: [PATCH] libstore/build: block io_uring Unfortunately, io_uring is totally opaque to seccomp, and while currently there are no dangerous operations implemented, there is no guarantee that it remains this way. This means that io_uring should be blocked entirely to ensure that the sandbox is future-proof. This has not been observed to cause issues in practice. Change-Id: I45d3895f95abe1bc103a63969f444c334dbbf50d --- doc/manual/rl-next/block-io-uring.md | 12 ++++++++++++ src/libstore/build/local-derivation-goal.cc | 6 +++--- tests/nixos/default.nix | 2 ++ tests/nixos/io_uring/default.nix | 7 +++++++ tests/nixos/io_uring/package.nix | 19 +++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 doc/manual/rl-next/block-io-uring.md create mode 100644 tests/nixos/io_uring/default.nix create mode 100644 tests/nixos/io_uring/package.nix diff --git a/doc/manual/rl-next/block-io-uring.md b/doc/manual/rl-next/block-io-uring.md new file mode 100644 index 000000000..6ebba9a20 --- /dev/null +++ b/doc/manual/rl-next/block-io-uring.md @@ -0,0 +1,12 @@ +--- +synopsis: "Block io_uring in the Linux sandbox" +cls: 1611 +credits: alois31 +category: Breaking Changes +--- + +The io\_uring API has the unfortunate property that it is not possible to selectively decide which operations should be allowed. +This, together with the fact that new operations are routinely added, makes it a hazard to the proper function of the sandbox. + +Therefore, any access to io\_uring has been made unavailable inside the sandbox. +As such, attempts to execute any system calls forming part of this API will fail with the error `ENOSYS`, as if io\_uring support had not been configured into the kernel. diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 33cbfb29d..1dbe66f72 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -1596,9 +1596,9 @@ void setupSeccomp() allowSyscall(ctx, SCMP_SYS(ioprio_set)); allowSyscall(ctx, SCMP_SYS(io_setup)); allowSyscall(ctx, SCMP_SYS(io_submit)); - allowSyscall(ctx, SCMP_SYS(io_uring_enter)); - allowSyscall(ctx, SCMP_SYS(io_uring_register)); - allowSyscall(ctx, SCMP_SYS(io_uring_setup)); + // skip io_uring_enter (may become dangerous) + // skip io_uring_register (may become dangerous) + // skip io_uring_setup (may become dangerous) allowSyscall(ctx, SCMP_SYS(ipc)); allowSyscall(ctx, SCMP_SYS(kcmp)); allowSyscall(ctx, SCMP_SYS(kexec_file_load)); diff --git a/tests/nixos/default.nix b/tests/nixos/default.nix index 301eede46..20e66f6c1 100644 --- a/tests/nixos/default.nix +++ b/tests/nixos/default.nix @@ -155,4 +155,6 @@ in broken-userns = runNixOSTestFor "x86_64-linux" ./broken-userns.nix; coredumps = runNixOSTestFor "x86_64-linux" ./coredumps; + + io_uring = runNixOSTestFor "x86_64-linux" ./io_uring; } diff --git a/tests/nixos/io_uring/default.nix b/tests/nixos/io_uring/default.nix new file mode 100644 index 000000000..9cd445d6a --- /dev/null +++ b/tests/nixos/io_uring/default.nix @@ -0,0 +1,7 @@ +let + inherit (import ../util.nix) mkNixBuildTest; +in +mkNixBuildTest { + name = "io_uring"; + expressionFile = ./package.nix; +} diff --git a/tests/nixos/io_uring/package.nix b/tests/nixos/io_uring/package.nix new file mode 100644 index 000000000..8f980183a --- /dev/null +++ b/tests/nixos/io_uring/package.nix @@ -0,0 +1,19 @@ +{ runCommandCC }: +runCommandCC "io_uring-is-blocked" { } '' + cat > test.c < + #include + #include + + int main() { + int res = syscall(SYS_io_uring_setup, 0, NULL); + return res == -1 && errno == ENOSYS ? 0 : 1; + } + EOF + "$CC" -o test test.c + if ! ./test; then + echo "Oh no! io_uring is available!" + exit 1 + fi + touch "$out" +''