diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix index e216351b4347..373bf7665240 100644 --- a/nixos/modules/testing/test-instrumentation.nix +++ b/nixos/modules/testing/test-instrumentation.nix @@ -110,6 +110,9 @@ let kernel = config.boot.kernelPackages.kernel; in networking.usePredictableInterfaceNames = false; + # Make sure we use a patched QEMU that ignores file ownership. + virtualisation.qemu.program = "${pkgs.qemu_test}/bin/qemu-kvm"; + # Make it easy to log in as root when running the test interactively. users.extraUsers.root.initialHashedPassword = mkOverride 150 ""; diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 777ee31e4dcc..263bbf785833 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -70,7 +70,7 @@ let '')} # Start QEMU. - exec ${pkgs.qemu_kvm}/bin/qemu-kvm \ + exec ${cfg.qemu.program} \ -name ${vmName} \ -m ${toString config.virtualisation.memorySize} \ ${optionalString (pkgs.stdenv.system == "x86_64-linux") "-cpu kvm64"} \ @@ -299,6 +299,14 @@ in }; virtualisation.qemu = { + program = mkOption { + type = types.path; + default = "${pkgs.qemu_kvm}/bin/qemu-kvm"; + defaultText = "\${pkgs.qemu_kvm}/bin/qemu-kvm"; + example = literalExample "\${pkgs.qemu_test}/bin/qemu-kvm"; + description = "The QEMU variant used to start the VM."; + }; + options = mkOption { type = types.listOf types.unspecified; diff --git a/pkgs/applications/virtualization/qemu/default.nix b/pkgs/applications/virtualization/qemu/default.nix index f81781987ccc..513eedc3438e 100644 --- a/pkgs/applications/virtualization/qemu/default.nix +++ b/pkgs/applications/virtualization/qemu/default.nix @@ -11,6 +11,7 @@ , vncSupport ? true, libjpeg, libpng , spiceSupport ? !stdenv.isDarwin, spice, spice_protocol, usbredir , x86Only ? false +, nixosTestRunner ? false }: with stdenv.lib; @@ -118,7 +119,7 @@ stdenv.mkDerivation rec { # from http://git.qemu.org/?p=qemu.git;a=patch;h=ff55e94d23ae94c8628b0115320157c763eb3e06 ./CVE-2016-9102.patch - ]; + ] ++ optional nixosTestRunner ./force-uid0-on-9p.patch; hardeningDisable = [ "stackprotector" ]; configureFlags = diff --git a/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch b/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch new file mode 100644 index 000000000000..90269961fdf3 --- /dev/null +++ b/pkgs/applications/virtualization/qemu/force-uid0-on-9p.patch @@ -0,0 +1,48 @@ +diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c +index 845675e..43fa036 100644 +--- a/hw/9pfs/9p-local.c ++++ b/hw/9pfs/9p-local.c +@@ -128,6 +128,8 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) + if (err) { + goto err_out; + } ++ stbuf->st_uid = 0; ++ stbuf->st_gid = 0; + if (fs_ctx->export_flags & V9FS_SM_MAPPED) { + /* Actual credentials are part of extended attrs */ + uid_t tmp_uid; +@@ -462,6 +464,16 @@ static ssize_t local_pwritev(FsContext *ctx, V9fsFidOpenState *fs, + return ret; + } + ++static int maybe_chmod(const char *path, mode_t mode) ++{ ++ static char *store_path = NULL; ++ if (store_path == NULL) ++ store_path = getenv("NIX_STORE"); ++ if (strncmp(path, store_path, strlen(store_path)) != 0) ++ return chmod(path, mode); ++ return 0; ++} ++ + static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) + { + char *buffer; +@@ -477,7 +489,7 @@ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) + } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || + (fs_ctx->export_flags & V9FS_SM_NONE)) { + buffer = rpath(fs_ctx, path); +- ret = chmod(buffer, credp->fc_mode); ++ ret = maybe_chmod(buffer, credp->fc_mode); + g_free(buffer); + } + return ret; +@@ -621,6 +633,8 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, + if (err) { + return err; + } ++ stbuf->st_uid = 0; ++ stbuf->st_gid = 0; + if (fs_ctx->export_flags & V9FS_SM_MAPPED) { + /* Actual credentials are part of extended attrs */ + uid_t tmp_uid; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 33dd7572e4c8..6b98d78e4555 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11358,6 +11358,7 @@ in watch = callPackage ../os-specific/linux/procps/watch.nix { }; qemu_kvm = lowPrio (qemu.override { x86Only = true; }); + qemu_test = lowPrio (qemu.override { x86Only = true; nixosTestRunner = true; }); firmwareLinuxNonfree = callPackage ../os-specific/linux/firmware/firmware-linux-nonfree { };