[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#699409: unblock: libvirt/0.9.12-6



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package libvirt

since it fixes 

* CVE-2013-0170
* a bug in the dependencies (#699128)
* Fixes a possible daemon crash with KVM (#699281)
* fixes a client deadlock (without a bugnumber)

The debdiff is attached. I tried to keep it as minimal as possible.
Cheers,
 -- Guido

unblock libvirt/0.9.12-6

-- System Information:
Debian Release: 7.0
  APT prefers testing
  APT policy: (990, 'testing'), (50, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)

Kernel: Linux 3.2.0-4-686-pae (SMP w/2 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff -Nru libvirt-0.9.12/debian/changelog libvirt-0.9.12/debian/changelog
--- libvirt-0.9.12/debian/changelog	2012-09-14 22:36:46.000000000 +0200
+++ libvirt-0.9.12/debian/changelog	2013-01-29 21:29:50.000000000 +0100
@@ -1,3 +1,18 @@
+libvirt (0.9.12-6) unstable; urgency=low
+
+  * [78a3a68] Revert "rpc: Discard non-blocking calls only when necessary"
+    Thanks to Jiri Denemark for the patch and Philipp Hahn for debugging
+  * [5b4dc1a] qemu: Fix off-by-one error while unescaping monitor strings.
+    Thanks to Peter Krempa for the patch and Philipp Hahn for debugging this
+    (Closes: #699281)
+  * [372f53d] rpc: Fix crash on error paths of message dispatching.
+    This fixes CVE-2013-0170
+    Thanks to Peter Krempa (Closes: #699224)
+  * [2a2a60e] Make python-libvirt depend on the exact same libvirt0 version
+    (Closes: #697852, #699128)
+
+ -- Guido Günther <agx@sigxcpu.org>  Tue, 29 Jan 2013 21:02:05 +0100
+
 libvirt (0.9.12-5) unstable; urgency=high
 
   * Setting urgency to high since it's a security only fix
diff -Nru libvirt-0.9.12/debian/control libvirt-0.9.12/debian/control
--- libvirt-0.9.12/debian/control	2012-09-14 21:36:27.000000000 +0200
+++ libvirt-0.9.12/debian/control	2013-01-29 21:28:36.000000000 +0100
@@ -124,7 +124,7 @@
 
 Package: python-libvirt
 Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, libvirt0 (>= ${binary:Version})
+Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, libvirt0 (= ${binary:Version})
 Provides: ${python:Provides}
 Recommends: libvirt-bin
 Section: python
diff -Nru libvirt-0.9.12/debian/patches/qemu-Fix-off-by-one-error-while-unescaping-monitor-s.patch libvirt-0.9.12/debian/patches/qemu-Fix-off-by-one-error-while-unescaping-monitor-s.patch
--- libvirt-0.9.12/debian/patches/qemu-Fix-off-by-one-error-while-unescaping-monitor-s.patch	1970-01-01 01:00:00.000000000 +0100
+++ libvirt-0.9.12/debian/patches/qemu-Fix-off-by-one-error-while-unescaping-monitor-s.patch	2013-01-29 21:27:40.000000000 +0100
@@ -0,0 +1,55 @@
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Thu, 14 Jun 2012 10:29:36 +0200
+Subject: qemu: Fix off-by-one error while unescaping monitor strings
+
+While unescaping the commands the commands passed through to the monitor
+function qemuMonitorUnescapeArg() initialized lenght of the input string
+to strlen()+1 which is fine for alloc but not for iteration of the
+string.
+
+This patch fixes the off-by-one error and drops the pointless check for
+a single trailing slash that is automaticaly handled by the default
+branch of switch.
+
+Closes: #699281
+Thanks: Philipp Hahn for debugging this
+---
+ src/qemu/qemu_monitor.c |   11 +++--------
+ 1 file changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
+index 0d4319d..68ecdb9 100644
+--- a/src/qemu/qemu_monitor.c
++++ b/src/qemu/qemu_monitor.c
+@@ -157,20 +157,15 @@ char *qemuMonitorUnescapeArg(const char *in)
+ {
+     int i, j;
+     char *out;
+-    int len = strlen(in) + 1;
++    int len = strlen(in);
+     char next;
+ 
+-    if (VIR_ALLOC_N(out, len) < 0)
++    if (VIR_ALLOC_N(out, len + 1) < 0)
+         return NULL;
+ 
+     for (i = j = 0; i < len; ++i) {
+         next = in[i];
+         if (in[i] == '\\') {
+-            if (len < i + 1) {
+-                /* trailing backslash shouldn't be possible */
+-                VIR_FREE(out);
+-                return NULL;
+-            }
+             ++i;
+             switch(in[i]) {
+             case 'r':
+@@ -184,7 +179,7 @@ char *qemuMonitorUnescapeArg(const char *in)
+                 next = in[i];
+                 break;
+             default:
+-                /* invalid input */
++                /* invalid input (including trailing '\' at end of in) */
+                 VIR_FREE(out);
+                 return NULL;
+             }
diff -Nru libvirt-0.9.12/debian/patches/Revert-rpc-Discard-non-blocking-calls-only-when-nece.patch libvirt-0.9.12/debian/patches/Revert-rpc-Discard-non-blocking-calls-only-when-nece.patch
--- libvirt-0.9.12/debian/patches/Revert-rpc-Discard-non-blocking-calls-only-when-nece.patch	1970-01-01 01:00:00.000000000 +0100
+++ libvirt-0.9.12/debian/patches/Revert-rpc-Discard-non-blocking-calls-only-when-nece.patch	2013-01-29 21:27:40.000000000 +0100
@@ -0,0 +1,67 @@
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Mon, 21 May 2012 16:02:05 +0200
+Subject: Revert "rpc: Discard non-blocking calls only when necessary"
+
+This reverts commit b1e374a7ac56927cfe62435179bf0bba1e08b372, which was
+rather bad since I failed to consider all sides of the issue. The main
+things I didn't consider properly are:
+
+- a thread which sends a non-blocking call waits for the thread with
+  the buck to process the call
+- the code doesn't expect non-blocking calls to remain in the queue
+  unless they were already partially sent
+
+Thus, the reverted patch actually breaks more than what it fixes and
+clients (which may even be libvirtd during p2p migrations) will likely
+end up in a deadlock.
+---
+ src/rpc/virnetclient.c |   21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
+index 3a60db6..d88288d 100644
+--- a/src/rpc/virnetclient.c
++++ b/src/rpc/virnetclient.c
+@@ -1265,13 +1265,6 @@ static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetCli
+     }
+     client->haveTheBuck = false;
+ 
+-    /* Remove non-blocking calls from the dispatch list since there is no
+-     * call with a thread in the list which could take care of them.
+-     */
+-    virNetClientCallRemovePredicate(&client->waitDispatch,
+-                                    virNetClientIOEventLoopRemoveNonBlocking,
+-                                    thiscall);
+-
+     VIR_DEBUG("No thread to pass the buck to");
+     if (client->wantClose) {
+         virNetClientCloseLocked(client);
+@@ -1315,9 +1308,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
+         if (virNetSocketHasCachedData(client->sock) || client->wantClose)
+             timeout = 0;
+ 
+-        /* If we are non-blocking, we don't want to sleep in poll()
++        /* If there are any non-blocking calls in the queue,
++         * then we don't want to sleep in poll()
+          */
+-        if (thiscall->nonBlock)
++        if (virNetClientCallMatchPredicate(client->waitDispatch,
++                                           virNetClientIOEventLoopWantNonBlock,
++                                           NULL))
+             timeout = 0;
+ 
+         fds[0].events = fds[0].revents = 0;
+@@ -1422,6 +1418,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
+                                         virNetClientIOEventLoopRemoveDone,
+                                         thiscall);
+ 
++        /* Iterate through waiting calls and if any are
++         * non-blocking, remove them from the dispatch list...
++         */
++        virNetClientCallRemovePredicate(&client->waitDispatch,
++                                        virNetClientIOEventLoopRemoveNonBlocking,
++                                        thiscall);
++
+         /* Now see if *we* are done */
+         if (thiscall->mode == VIR_NET_CLIENT_MODE_COMPLETE) {
+             virNetClientCallRemove(&client->waitDispatch, thiscall);
diff -Nru libvirt-0.9.12/debian/patches/rpc-Fix-crash-on-error-paths-of-message-dispatching.patch libvirt-0.9.12/debian/patches/rpc-Fix-crash-on-error-paths-of-message-dispatching.patch
--- libvirt-0.9.12/debian/patches/rpc-Fix-crash-on-error-paths-of-message-dispatching.patch	1970-01-01 01:00:00.000000000 +0100
+++ libvirt-0.9.12/debian/patches/rpc-Fix-crash-on-error-paths-of-message-dispatching.patch	2013-01-29 21:27:40.000000000 +0100
@@ -0,0 +1,51 @@
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Fri, 4 Jan 2013 16:15:04 +0100
+Subject: rpc: Fix crash on error paths of message dispatching
+
+This patch resolves CVE-2013-0170:
+https://bugzilla.redhat.com/show_bug.cgi?id=893450
+
+When reading and dispatching of a message failed the message was freed
+but wasn't removed from the message queue.
+
+After that when the connection was about to be closed the pointer for
+the message was still present in the queue and it was passed to
+virNetMessageFree which tried to call the callback function from an
+uninitialized pointer.
+
+This patch removes the message from the queue before it's freed.
+
+* rpc/virnetserverclient.c: virNetServerClientDispatchRead:
+    - avoid use after free of RPC messages
+---
+ src/rpc/virnetserverclient.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
+index 67600fd..3838136 100644
+--- a/src/rpc/virnetserverclient.c
++++ b/src/rpc/virnetserverclient.c
+@@ -840,6 +840,7 @@ readmore:
+ 
+         /* Decode the header so we can use it for routing decisions */
+         if (virNetMessageDecodeHeader(msg) < 0) {
++            virNetMessageQueueServe(&client->rx);
+             virNetMessageFree(msg);
+             client->wantClose = true;
+             return;
+@@ -849,6 +850,7 @@ readmore:
+          * file descriptors */
+         if (msg->header.type == VIR_NET_CALL_WITH_FDS &&
+             virNetMessageDecodeNumFDs(msg) < 0) {
++            virNetMessageQueueServe(&client->rx);
+             virNetMessageFree(msg);
+             client->wantClose = true;
+             return; /* Error */
+@@ -858,6 +860,7 @@ readmore:
+         for (i = msg->donefds ; i < msg->nfds ; i++) {
+             int rv;
+             if ((rv = virNetSocketRecvFD(client->sock, &(msg->fds[i]))) < 0) {
++                virNetMessageQueueServe(&client->rx);
+                 virNetMessageFree(msg);
+                 client->wantClose = true;
+                 return;
diff -Nru libvirt-0.9.12/debian/patches/series libvirt-0.9.12/debian/patches/series
--- libvirt-0.9.12/debian/patches/series	2012-09-14 22:36:14.000000000 +0200
+++ libvirt-0.9.12/debian/patches/series	2013-01-29 21:27:40.000000000 +0100
@@ -14,3 +14,6 @@
 Include-stdint.h-for-uint32_t.patch
 security/CVE-2012-3445.patch
 security/security-Fix-libvirtd-crash-possibility.patch
+Revert-rpc-Discard-non-blocking-calls-only-when-nece.patch
+qemu-Fix-off-by-one-error-while-unescaping-monitor-s.patch
+rpc-Fix-crash-on-error-paths-of-message-dispatching.patch

Reply to: