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)