diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 551cc20fd8b027bb2f35f6f300d5142e0fbfedf2..7c9f2712cdffb014b27a98ae2c6489023fff7e4b 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -39,6 +39,7 @@ module Libvirtd_qemu = | str_entry "hugetlbfs_mount" | bool_entry "relaxed_acs_check" | bool_entry "vnc_allow_host_audio" + | bool_entry "clear_emulator_capabilities" (* Each enty in the config is one of the following three ... *) let entry = vnc_entry diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 98a117693f20bf58980b55afb0a842fbdc571ab1..93934f3982e5f041d40649d8a6017c79a8f96f98 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -178,3 +178,12 @@ # QEMU_AUDIO_DRV environment variable when using VNC. # # vnc_allow_host_audio = 0 + +# If clear_emulator_capabilities is enabled, libvirt will drop all +# privileged capabilities of the QEmu/KVM emulator. This is enabled by +# default. +# +# Warning: Disabling this option means that a compromised guest can +# exploit the privileges and possibly do damage to the host. +# +# clear_emulator_capabilities = 1 diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 33e6b38c5bb5ebe30e4d2dde12787f3d8677d3d7..16d2f44d746105fbbc3c34c5c8ca31c41729b24e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -104,6 +104,7 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, /* Setup critical defaults */ driver->dynamicOwnership = 1; + driver->clearEmulatorCapabilities = 1; if (!(driver->vncListen = strdup("127.0.0.1"))) { virReportOOMError(); @@ -355,6 +356,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG); if (p) driver->vncAllowHostAudio = p->l; + p = virConfGetValue (conf, "clear_emulator_capabilities"); + CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG); + if (p) driver->clearEmulatorCapabilities = p->l; + virConfFree (conf); return 0; } diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 7616d151b21f57453e6085ed91f0291b2d75ce86..0f8a1b3654a67447cfb569d9dd351e3c96fbf754 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -138,8 +138,8 @@ struct qemud_driver { ebtablesContext *ebtables; unsigned int relaxedACS : 1; - unsigned int vncAllowHostAudio : 1; + unsigned int clearEmulatorCapabilities : 1; virCapsPtr caps; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 477a221ac032052c6d542c57c0c076348a4f947c..c8cd50ad600c0913b6f2e0e147a4cf32b9778b2f 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3287,7 +3287,7 @@ static int qemudStartVMDaemon(virConnectPtr conn, int stdin_fd) { const char **argv = NULL, **tmp; const char **progenv = NULL; - int i, ret; + int i, ret, runflags; struct stat sb; int *vmfds = NULL; int nvmfds = 0; @@ -3501,9 +3501,16 @@ static int qemudStartVMDaemon(virConnectPtr conn, for (i = 0 ; i < nvmfds ; i++) FD_SET(vmfds[i], &keepfd); + VIR_DEBUG("Clear emulator capabilities: %d", + driver->clearEmulatorCapabilities); + runflags = VIR_EXEC_NONBLOCK; + if (driver->clearEmulatorCapabilities) { + runflags |= VIR_EXEC_CLEAR_CAPS; + } + ret = virExecDaemonize(argv, progenv, &keepfd, &child, stdin_fd, &logfile, &logfile, - VIR_EXEC_NONBLOCK | VIR_EXEC_CLEAR_CAPS, + runflags, qemudSecurityHook, &hookData, pidfile); VIR_FREE(pidfile); diff --git a/src/qemu/test_libvirtd_qemu.aug b/src/qemu/test_libvirtd_qemu.aug index a048ae55e6016cf6be911afb08ea53e76ccfd230..3326cc5331530cc2b07cae51a6832d43be5d9490 100644 --- a/src/qemu/test_libvirtd_qemu.aug +++ b/src/qemu/test_libvirtd_qemu.aug @@ -99,6 +99,8 @@ hugetlbfs_mount = \"/dev/hugepages\" relaxed_acs_check = 1 vnc_allow_host_audio = 1 + +clear_emulator_capabilities = 0 " test Libvirtd_qemu.lns get conf = @@ -208,3 +210,5 @@ vnc_allow_host_audio = 1 { "relaxed_acs_check" = "1" } { "#empty" } { "vnc_allow_host_audio" = "1" } +{ "#empty" } +{ "clear_emulator_capabilities" = "0" }