[libvirt] [PATCH 07/12] Switch QEMU driver over to use the DAC security driver

Daniel P. Berrange berrange at redhat.com
Wed Jan 20 15:15:04 UTC 2010


Remove all the QEMU driver calls for setting file ownership and
process uid/gid. Instead wire in the QEMU DAC security driver,
stacking it ontop of the primary SELinux/AppArmour driver.

* qemu/qemu_driver.c: Switch over to new DAC security driver
---
 src/qemu/qemu_driver.c       |  311 ++----------------------------------------
 src/qemu/qemu_security_dac.c |    2 +-
 2 files changed, 13 insertions(+), 300 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8195b74..9554852 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -69,7 +69,8 @@
 #include "pci.h"
 #include "hostusb.h"
 #include "processinfo.h"
-#include "security/security_driver.h"
+#include "qemu_security_stacked.h"
+#include "qemu_security_dac.h"
 #include "cgroup.h"
 #include "libvirt_internal.h"
 #include "xml.h"
@@ -936,7 +937,12 @@ qemudSecurityInit(struct qemud_driver *qemud_drv)
         return 0;
     }
 
-    qemud_drv->securityDriver = security_drv;
+    qemuSecurityStackedSetDriver(qemud_drv);
+    qemuSecurityDACSetDriver(qemud_drv);
+
+    qemud_drv->securityPrimaryDriver = security_drv;
+    qemud_drv->securitySecondaryDriver = &qemuDACSecurityDriver;
+    qemud_drv->securityDriver = &qemuStackedSecurityDriver;
 
     VIR_INFO("Initialized security driver %s", security_drv->name);
 
@@ -2438,225 +2444,6 @@ cleanup:
 }
 
 
-static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm)
-{
-    int rc = 0;
-
-    if (driver->securityDriver &&
-        driver->securityDriver->domainSetSecurityProcessLabel &&
-        driver->securityDriver->domainSetSecurityProcessLabel(conn, driver->securityDriver, vm) < 0)
-        rc = -1;
-
-    return rc;
-}
-
-
-#ifdef __linux__
-struct qemuFileOwner {
-    uid_t uid;
-    gid_t gid;
-};
-
-static int qemuDomainSetHostdevUSBOwnershipActor(virConnectPtr conn,
-                                                 usbDevice *dev ATTRIBUTE_UNUSED,
-                                                 const char *file, void *opaque)
-{
-    struct qemuFileOwner *owner = opaque;
-
-    VIR_DEBUG("Setting ownership on %s to %d:%d", file, owner->uid, owner->gid);
-
-    if (chown(file, owner->uid, owner->gid) < 0) {
-        virReportSystemError(conn, errno, _("cannot set ownership on %s"), file);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int qemuDomainSetHostdevUSBOwnership(virConnectPtr conn,
-                                            virDomainHostdevDefPtr def,
-                                            uid_t uid, gid_t gid)
-{
-    struct qemuFileOwner owner = { uid, gid };
-    int ret = -1;
-
-    usbDevice *dev = usbGetDevice(conn,
-                                  def->source.subsys.u.usb.bus,
-                                  def->source.subsys.u.usb.device,
-                                  def->source.subsys.u.usb.vendor,
-                                  def->source.subsys.u.usb.product);
-
-    if (!dev)
-        goto cleanup;
-
-    ret = usbDeviceFileIterate(conn, dev,
-                               qemuDomainSetHostdevUSBOwnershipActor, &owner);
-
-    usbFreeDevice(conn, dev);
-cleanup:
-    return ret;
-}
-
-static int qemuDomainSetHostdevPCIOwnershipActor(virConnectPtr conn,
-                                                 pciDevice *dev ATTRIBUTE_UNUSED,
-                                                 const char *file, void *opaque)
-{
-    struct qemuFileOwner *owner = opaque;
-
-    VIR_DEBUG("Setting ownership on %s to %d:%d", file, owner->uid, owner->gid);
-
-    if (chown(file, owner->uid, owner->gid) < 0) {
-        virReportSystemError(conn, errno, _("cannot set ownership on %s"), file);
-        return -1;
-    }
-
-    return 0;
-}
-
-static int qemuDomainSetHostdevPCIOwnership(virConnectPtr conn,
-                                            virDomainHostdevDefPtr def,
-                                            uid_t uid, gid_t gid)
-{
-    struct qemuFileOwner owner = { uid, gid };
-    int ret = -1;
-
-    pciDevice *dev = pciGetDevice(conn,
-                                  def->source.subsys.u.pci.domain,
-                                  def->source.subsys.u.pci.bus,
-                                  def->source.subsys.u.pci.slot,
-                                  def->source.subsys.u.pci.function);
-
-    if (!dev)
-        goto cleanup;
-
-    ret = pciDeviceFileIterate(conn, dev,
-                               qemuDomainSetHostdevPCIOwnershipActor, &owner);
-
-    pciFreeDevice(conn, dev);
-cleanup:
-    return ret;
-}
-#endif
-
-
-static int qemuDomainSetHostdevOwnership(virConnectPtr conn,
-                                         virDomainHostdevDefPtr def,
-                                         uid_t uid, gid_t gid)
-{
-    if (def->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
-        return 0;
-
-#ifdef __linux__
-    switch (def->source.subsys.type) {
-    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
-        return qemuDomainSetHostdevUSBOwnership(conn, def, uid, gid);
-
-    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
-        return qemuDomainSetHostdevPCIOwnership(conn, def, uid, gid);
-
-    }
-    return 0;
-#else
-    qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s",
-                     _("unable to set host device ownership on this platform"));
-    return -1;
-#endif
-
-}
-
-static int qemuDomainSetFileOwnership(virConnectPtr conn,
-                                      const char *path,
-                                      uid_t uid, gid_t gid)
-{
-
-    if (!path)
-        return 0;
-
-    VIR_DEBUG("Setting ownership on %s to %d:%d", path, uid, gid);
-    if (chown(path, uid, gid) < 0) {
-        virReportSystemError(conn, errno, _("cannot set ownership on %s"),
-                             path);
-        return -1;
-    }
-    return 0;
-}
-
-static int qemuDomainSetDeviceOwnership(virConnectPtr conn,
-                                        struct qemud_driver *driver,
-                                        virDomainDeviceDefPtr def,
-                                        int restore)
-{
-    uid_t uid;
-    gid_t gid;
-
-    if (!driver->privileged)
-        return 0;
-
-    /* short circuit case of root:root */
-    if (!driver->user && !driver->group)
-        return 0;
-
-    uid = restore ? 0 : driver->user;
-    gid = restore ? 0 : driver->group;
-
-    switch (def->type) {
-    case VIR_DOMAIN_DEVICE_DISK:
-        if (restore &&
-            (def->data.disk->readonly || def->data.disk->shared))
-            return 0;
-
-        return qemuDomainSetFileOwnership(conn, def->data.disk->src, uid, gid);
-
-    case VIR_DOMAIN_DEVICE_HOSTDEV:
-        return qemuDomainSetHostdevOwnership(conn, def->data.hostdev, uid, gid);
-    }
-
-    return 0;
-}
-
-static int qemuDomainSetAllDeviceOwnership(virConnectPtr conn,
-                                           struct qemud_driver *driver,
-                                           virDomainDefPtr def,
-                                           int restore)
-{
-    int i;
-    uid_t uid;
-    gid_t gid;
-
-    if (!driver->privileged)
-        return 0;
-
-    /* short circuit case of root:root */
-    if (!driver->user && !driver->group)
-        return 0;
-
-    uid = restore ? 0 : driver->user;
-    gid = restore ? 0 : driver->group;
-
-    if (qemuDomainSetFileOwnership(conn, def->os.kernel, uid, gid) < 0 ||
-        qemuDomainSetFileOwnership(conn, def->os.initrd, uid, gid) < 0)
-        return -1;
-
-    for (i = 0 ; i < def->ndisks ; i++) {
-        if (restore &&
-            (def->disks[i]->readonly || def->disks[i]->shared))
-            continue;
-
-        if (qemuDomainSetFileOwnership(conn, def->disks[i]->src, uid, gid) < 0)
-            return -1;
-    }
-
-    for (i = 0 ; i < def->nhostdevs ; i++) {
-        if (qemuDomainSetHostdevOwnership(conn, def->hostdevs[i], uid, gid) < 0)
-            return -1;
-    }
-
-    return 0;
-}
-
-static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
-                                            const char *name);
-
 struct qemudHookData {
     virConnectPtr conn;
     virDomainObjPtr vm;
@@ -2669,33 +2456,11 @@ static int qemudSecurityHook(void *data) {
     if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
         return -1;
 
-    if (qemudDomainSetSecurityLabel(h->conn, h->driver, h->vm) < 0)
+    if (h->driver->securityDriver &&
+        h->driver->securityDriver->domainSetSecurityProcessLabel &&
+        h->driver->securityDriver->domainSetSecurityProcessLabel(h->conn, h->driver->securityDriver, h->vm) < 0)
         return -1;
 
-    if (h->driver->privileged) {
-        if (qemuDomainSetAllDeviceOwnership(h->conn, h->driver, h->vm->def, 0) < 0)
-            return -1;
-
-        DEBUG("Dropping privileges of VM to %d:%d", h->driver->user, h->driver->group);
-
-        if (h->driver->group) {
-            if (setregid(h->driver->group, h->driver->group) < 0) {
-                virReportSystemError(NULL, errno,
-                                     _("cannot change to '%d' group"),
-                                     h->driver->group);
-                return -1;
-            }
-        }
-        if (h->driver->user) {
-            if (setreuid(h->driver->user, h->driver->user) < 0) {
-                virReportSystemError(NULL, errno,
-                                     _("cannot change to '%d' user"),
-                                     h->driver->user);
-                return -1;
-            }
-        }
-    }
-
     return 0;
 }
 
@@ -3078,10 +2843,6 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
     virDomainDefClearPCIAddresses(vm->def);
     virDomainDefClearDeviceAliases(vm->def);
 
-    if (qemuDomainSetAllDeviceOwnership(conn, driver, vm->def, 1) < 0)
-        VIR_WARN("Failed to restore all device ownership for %s",
-                 vm->def->name);
-
     qemuDomainReAttachHostDevices(conn, driver, vm->def);
 
 retry:
@@ -4132,14 +3893,6 @@ static int qemudDomainSave(virDomainPtr dom,
     }
     fd = -1;
 
-    if (driver->privileged &&
-        chown(path, driver->user, driver->group) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("unable to set ownership of '%s' to user %d:%d"),
-                             path, driver->user, driver->group);
-        goto endjob;
-    }
-
     if (driver->securityDriver &&
         driver->securityDriver->domainSetSavedStateLabel &&
         driver->securityDriver->domainSetSavedStateLabel(dom->conn, vm, path) == -1)
@@ -4167,14 +3920,6 @@ static int qemudDomainSave(virDomainPtr dom,
     if (rc < 0)
         goto endjob;
 
-    if (driver->privileged &&
-        chown(path, 0, 0) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("unable to set ownership of '%s' to user %d:%d"),
-                             path, 0, 0);
-        goto endjob;
-    }
-
     if (driver->securityDriver &&
         driver->securityDriver->domainRestoreSavedStateLabel &&
         driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, vm, path) == -1)
@@ -4262,14 +4007,6 @@ static int qemudDomainCoreDump(virDomainPtr dom,
         goto endjob;
     }
 
-    if (driver->privileged &&
-        chown(path, driver->user, driver->group) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("unable to set ownership of '%s' to user %d:%d"),
-                             path, driver->user, driver->group);
-        goto endjob;
-    }
-
     if (driver->securityDriver &&
         driver->securityDriver->domainSetSavedStateLabel &&
         driver->securityDriver->domainSetSavedStateLabel(dom->conn, vm, path) == -1)
@@ -4297,14 +4034,6 @@ static int qemudDomainCoreDump(virDomainPtr dom,
     qemuDomainObjExitMonitor(vm);
     paused |= (ret == 0);
 
-    if (driver->privileged &&
-        chown(path, 0, 0) < 0) {
-        virReportSystemError(NULL, errno,
-                             _("unable to set ownership of '%s' to user %d:%d"),
-                             path, 0, 0);
-        goto endjob;
-    }
-
     if (driver->securityDriver &&
         driver->securityDriver->domainRestoreSavedStateLabel &&
         driver->securityDriver->domainRestoreSavedStateLabel(dom->conn, vm, path) == -1)
@@ -5879,8 +5608,6 @@ static int qemudDomainAttachHostDevice(virConnectPtr conn,
         return -1;
     }
 
-    if (qemuDomainSetDeviceOwnership(conn, driver, dev, 0) < 0)
-        return -1;
     if (driver->securityDriver &&
         driver->securityDriver->domainSetSecurityHostdevLabel &&
         driver->securityDriver->domainSetSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
@@ -5963,9 +5690,6 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
                 driver->securityDriver->domainSetSecurityImageLabel)
                 driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
 
-            if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
-                goto endjob;
-
             ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev);
             break;
 
@@ -5974,9 +5698,6 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
                 driver->securityDriver->domainSetSecurityImageLabel)
                 driver->securityDriver->domainSetSecurityImageLabel(dom->conn, vm, dev->data.disk);
 
-            if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0)
-                goto endjob;
-
             if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
                 ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev);
             } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
@@ -6032,11 +5753,8 @@ cleanup:
     if (cgroup)
         virCgroupFree(&cgroup);
 
-    if (ret < 0 && dev != NULL) {
-        if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 1) < 0)
-            VIR_WARN0("Fail to restore disk device ownership");
+    if (ret < 0 && dev != NULL)
         virDomainDeviceDefFree(dev);
-    }
     if (vm)
         virDomainObjUnlock(vm);
     qemuDriverUnlock(driver);
@@ -6365,9 +6083,6 @@ static int qemudDomainDetachHostDevice(virConnectPtr conn,
         driver->securityDriver->domainSetSecurityHostdevLabel(conn, vm, dev->data.hostdev) < 0)
         VIR_WARN0("Failed to restore device labelling");
 
-    if (qemuDomainSetDeviceOwnership(conn, driver, dev, 1) < 0)
-        VIR_WARN0("Failed to restore device ownership");
-
     return ret;
 }
 
@@ -6410,8 +6125,6 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
         if (driver->securityDriver &&
             driver->securityDriver->domainRestoreSecurityImageLabel)
             driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, vm, dev->data.disk);
-        if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 1) < 0)
-            VIR_WARN0("Fail to restore disk device ownership");
     } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
         ret = qemudDomainDetachNetDevice(dom->conn, driver, vm, dev);
     } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
index 6b7aab5..623aa55 100644
--- a/src/qemu/qemu_security_dac.c
+++ b/src/qemu/qemu_security_dac.c
@@ -439,7 +439,7 @@ qemuSecurityDACSetProcessLabel(virConnectPtr conn ATTRIBUTE_UNUSED,
 
 
 
-virSecurityDriver virqemuSecurityDACSecurityDriver = {
+virSecurityDriver qemuDACSecurityDriver = {
     .name                       = "qemuDAC",
 
     .domainSetSecurityProcessLabel = qemuSecurityDACSetProcessLabel,
-- 
1.6.5.2




More information about the libvir-list mailing list