Package: libvirt
Version: 0.4.6-5
Severity: normal
Tags: patch
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu jaunty ubuntu-patch

In Ubuntu, we've applied the attached patch to achieve the following:

  * SECURITY UPDATE: fix privilege escalation due to missing read only
    connection checks
    - debian/patches/0009-CVE-2008-5086.patch: update functions in
      src/libvirt.c to check against VIR_CONNECT_RO and return with operation
      denied error
    - CVE-2008-5086

We thought you might be interested in doing the same. Note that the
attached patch is against Ubuntu's libvirt, which contains a qemu
migration patch backported from upstream git. As such, this should
apply to 0.5.1 in experimental, and you can leave out the patches to
virDomainMigratePrepare2 and virDomainMigrateFinish2 for sid. Patch
originated from Redhat.

Excerpted from the Ubuntu USN:
It was discovered that libvirt did not mark certain operations as
read-only. A local attacker may be able to perform privileged actions
such as migrating virtual machines, adjusting autostart flags, or
accessing privileged data in the virtual machine memory and disks.
diff -u libvirt-0.4.6/debian/changelog libvirt-0.4.6/debian/changelog
diff -u libvirt-0.4.6/debian/patches/series libvirt-0.4.6/debian/patches/series
--- libvirt-0.4.6/debian/patches/series
+++ libvirt-0.4.6/debian/patches/series
@@ -10,0 +11 @@
+0009-CVE-2008-5086.patch
only in patch2:
unchanged:
--- libvirt-0.4.6.orig/debian/patches/0009-CVE-2008-5086.patch
+++ libvirt-0.4.6/debian/patches/0009-CVE-2008-5086.patch
@@ -0,0 +1,156 @@
+#
+# Reference: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5086
+# Description: add missing read-only connection flag check
+#
+diff -Nur libvirt-0.4.6/src/libvirt.c libvirt-0.4.6.new/src/libvirt.c
+--- libvirt-0.4.6/src/libvirt.c	2008-12-16 10:46:30.000000000 -0600
++++ libvirt-0.4.6.new/src/libvirt.c	2008-12-16 10:46:44.000000000 -0600
+@@ -2181,6 +2181,16 @@
+         return NULL;
+     }
+ 
++    if (domain->conn->flags & VIR_CONNECT_RO) {
++        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return NULL;
++    }
++    if (dconn->flags & VIR_CONNECT_RO) {
++        /* NB, delibrately report error against source object, not dest here */
++        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return NULL;
++    }
++
+     /* Check that migration is supported by both drivers. */
+     if (VIR_DRV_SUPPORTS_FEATURE (conn->driver, conn,
+                                   VIR_DRV_FEATURE_MIGRATION_V1) &&
+@@ -2307,6 +2317,11 @@
+         return -1;
+     }
+ 
++    if (dconn->flags & VIR_CONNECT_RO) {
++        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return -1;
++    }
++
+     if (dconn->driver->domainMigratePrepare)
+         return dconn->driver->domainMigratePrepare (dconn, cookie, cookielen,
+                                                     uri_in, uri_out,
+@@ -2337,6 +2352,11 @@
+     }
+     conn = domain->conn;
+ 
++    if (domain->conn->flags & VIR_CONNECT_RO) {
++        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return -1;
++    }
++
+     if (conn->driver->domainMigratePerform)
+         return conn->driver->domainMigratePerform (domain, cookie, cookielen,
+                                                    uri,
+@@ -2364,6 +2384,11 @@
+         return NULL;
+     }
+ 
++    if (dconn->flags & VIR_CONNECT_RO) {
++        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return NULL;
++    }
++
+     if (dconn->driver->domainMigrateFinish)
+         return dconn->driver->domainMigrateFinish (dconn, dname,
+                                                    cookie, cookielen,
+@@ -2395,6 +2420,11 @@
+         return -1;
+     }
+ 
++    if (dconn->flags & VIR_CONNECT_RO) {
++        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return -1;
++    }
++
+     if (dconn->driver->domainMigratePrepare2)
+         return dconn->driver->domainMigratePrepare2 (dconn, cookie, cookielen,
+                                                      uri_in, uri_out,
+@@ -2424,6 +2454,11 @@
+         return NULL;
+     }
+ 
++    if (dconn->flags & VIR_CONNECT_RO) {
++        virLibConnError(dconn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return NULL;
++    }
++
+     if (dconn->driver->domainMigrateFinish2)
+         return dconn->driver->domainMigrateFinish2 (dconn, dname,
+                                                     cookie, cookielen,
+@@ -2782,6 +2817,11 @@
+     }
+     conn = dom->conn;
+ 
++    if (dom->conn->flags & VIR_CONNECT_RO) {
++        virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return (-1);
++    }
++
+     if (!path) {
+         virLibDomainError (dom, VIR_ERR_INVALID_ARG,
+                            _("path is NULL"));
+@@ -2857,6 +2897,11 @@
+     }
+     conn = dom->conn;
+ 
++    if (dom->conn->flags & VIR_CONNECT_RO) {
++        virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return (-1);
++    }
++
+     /* Flags must be VIR_MEMORY_VIRTUAL at the moment.
+      *
+      * Note on access to physical memory: A VIR_MEMORY_PHYSICAL flag is
+@@ -3124,6 +3169,11 @@
+ 
+     conn = domain->conn;
+ 
++    if (domain->conn->flags & VIR_CONNECT_RO) {
++        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return (-1);
++    }
++
+     if (conn->driver->domainSetAutostart)
+         return conn->driver->domainSetAutostart (domain, autostart);
+ 
+@@ -4074,6 +4124,11 @@
+         return (-1);
+     }
+ 
++    if (network->conn->flags & VIR_CONNECT_RO) {
++        virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return (-1);
++    }
++
+     conn = network->conn;
+ 
+     if (conn->networkDriver && conn->networkDriver->networkSetAutostart)
+@@ -4272,6 +4327,11 @@
+         return NULL;
+     }
+ 
++    if (conn->flags & VIR_CONNECT_RO) {
++        virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return NULL;
++    }
++
+     if (conn->storageDriver && conn->storageDriver->findPoolSources)
+         return conn->storageDriver->findPoolSources(conn, type, srcSpec, flags);
+ 
+@@ -4945,6 +5005,11 @@
+         return (-1);
+     }
+ 
++    if (pool->conn->flags & VIR_CONNECT_RO) {
++        virLibStoragePoolError(pool, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
++        return (-1);
++    }
++
+     conn = pool->conn;
+ 
+     if (conn->storageDriver && conn->storageDriver->poolSetAutostart)

Reply via email to