diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index f3cc9e6843..de723b2543 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -70,6 +70,7 @@ module Libvirtd_qemu = | str_array_entry "cgroup_controllers" | str_array_entry "cgroup_device_acl" | int_entry "seccomp_sandbox" + | str_array_entry "namespaces" let save_entry = str_entry "save_image_format" | str_entry "dump_image_format" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 2b2bd6031f..a8cd369cba 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -665,3 +665,11 @@ # Defaults to 4 # #gluster_debug_level = 9 + +# To enhance security, QEMU driver is capable of creating private namespaces +# for each domain started. Well, so far only "mount" namespace is supported. If +# enabled it means qemu process is unable to see all the devices on the system, +# only those configured for the domain in question. Libvirt then manages +# devices entries throughout the domain lifetime. This namespace is turned on +# by default. +#namespaces = [ "mount" ] diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 23a5504e18..86170fb7ae 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -314,6 +314,12 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) cfg->glusterDebugLevel = 4; cfg->stdioLogD = true; + if (!(cfg->namespaces = virBitmapNew(QEMU_DOMAIN_NS_LAST))) + goto error; + + if (virBitmapSetBit(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT) < 0) + goto error; + #ifdef DEFAULT_LOADER_NVRAM if (virFirmwareParseList(DEFAULT_LOADER_NVRAM, &cfg->firmwares, @@ -349,6 +355,7 @@ static void virQEMUDriverConfigDispose(void *obj) { virQEMUDriverConfigPtr cfg = obj; + virBitmapFree(cfg->namespaces); virStringListFree(cfg->cgroupDeviceACL); @@ -433,6 +440,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, char **hugetlbfs = NULL; char **nvram = NULL; char *corestr = NULL; + char **namespaces = NULL; /* Just check the file is readable before opening it, otherwise * libvirt emits an error. @@ -798,6 +806,31 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, if (virConfGetValueUInt(conf, "gluster_debug_level", &cfg->glusterDebugLevel) < 0) goto cleanup; + if (virConfGetValueStringList(conf, "namespaces", false, &namespaces) < 0) + goto cleanup; + + if (namespaces) { + virBitmapClearAll(cfg->namespaces); + + for (i = 0; namespaces[i]; i++) { + int ns = qemuDomainNamespaceTypeFromString(namespaces[i]); + + if (ns < 0) { + virReportError(VIR_ERR_CONF_SYNTAX, + _("Unknown namespace: %s"), + namespaces[i]); + goto cleanup; + } + + if (virBitmapSetBit(cfg->namespaces, ns) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to enable namespace: %s"), + namespaces[i]); + goto cleanup; + } + } + } + ret = 0; cleanup: diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index d191e10565..92a7a50278 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -90,6 +90,8 @@ struct _virQEMUDriverConfig { gid_t group; bool dynamicOwnership; + virBitmapPtr namespaces; + int cgroupControllers; char **cgroupDeviceACL; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 52fe7c01aa..12114ce700 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7366,7 +7366,8 @@ qemuDomainCreateNamespace(virQEMUDriverPtr driver, char **devMountsPath = NULL; size_t ndevMountsPath = 0, i; - if (!virQEMUDriverIsPrivileged(driver)) { + if (!virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT) || + !virQEMUDriverIsPrivileged(driver)) { ret = 0; goto cleanup; } diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in index f586e956de..a749f09004 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -91,3 +91,6 @@ module Test_libvirtd_qemu = } { "stdio_handler" = "logd" } { "gluster_debug_level" = "9" } +{ "namespaces" + { "1" = "mount" } +}