29.06.2011 00:31, Michael Tokarev wrote:
> Additional information:
> http://patchwork.ozlabs.org/patch/94604/ (upstream patch)
> https://bugzilla.redhat.com/show_bug.cgi?id=717399
> 
> The problem affects both sqeeze and sid versions.  It is present in
> lenny too, but that one is hopeless (we should provide fixes for
> lenny backports instead).

Actually, lenny version (kvm-72) is _not_ affected, -- the original
first implementation was correct, the bug has been introduced later
when the code has been refactored and moved to a separate function.
So only squeeze and sid versions are affected (and bpo50).

I updated both packages in collab-maint git (and the bugreport)
to mention the newly assigned CVE-2011-2512 (renamed the patch
accordingly and updated the changelog entry).  New debdiff is
attached.

Thank you!

/mjt
diff -u qemu-kvm-0.12.5+dfsg/debian/changelog 
qemu-kvm-0.12.5+dfsg/debian/changelog
--- qemu-kvm-0.12.5+dfsg/debian/changelog
+++ qemu-kvm-0.12.5+dfsg/debian/changelog
@@ -1,3 +1,10 @@
+qemu-kvm (0.12.5+dfsg-5+squeeze4) stable; urgency=high
+
+  * virtio: guard against negative vq notifies -- fixes a guest-triggerable
+    bug in virtio implementation (CVE-2011-2512) (Closes: #631975)
+
+ -- Michael Tokarev <m...@tls.msk.ru>  Wed, 29 Jun 2011 00:44:36 +0400
+
 qemu-kvm (0.12.5+dfsg-5+squeeze3) stable; urgency=low
 
   * cirrus_vga:fix-division-by-0-for-color-expansion-rop-92d675d1c1.diff
diff -u qemu-kvm-0.12.5+dfsg/debian/patches/series 
qemu-kvm-0.12.5+dfsg/debian/patches/series
--- qemu-kvm-0.12.5+dfsg/debian/patches/series
+++ qemu-kvm-0.12.5+dfsg/debian/patches/series
@@ -45,0 +46 @@
+virtio-guard-against-negative-vq-notifies-CVE-2011-2512.diff
only in patch2:
unchanged:
--- 
qemu-kvm-0.12.5+dfsg.orig/debian/patches/virtio-guard-against-negative-vq-notifies-CVE-2011-2512.diff
+++ 
qemu-kvm-0.12.5+dfsg/debian/patches/virtio-guard-against-negative-vq-notifies-CVE-2011-2512.diff
@@ -0,0 +1,62 @@
+upstream commit 7157e2e23e89adcd436caeab31fdd6b47eded377
+Author: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com>
+Date:   Sun May 8 22:29:07 2011 +0100
+
+    virtio: guard against negative vq notifies
+    
+    The virtio_queue_notify() function checks that the virtqueue number is
+    less than the maximum number of virtqueues.  A signed comparison is used
+    but the virtqueue number could be negative if a buggy or malicious guest
+    is run.  This results in memory accesses outside of the virtqueue array.
+    
+    It is risky doing input validation in common code instead of at the
+    guest<->host boundary.  Note that virtio_queue_set_addr(),
+    virtio_queue_get_addr(), virtio_queue_get_num(), and many other virtio
+    functions do *not* validate the virtqueue number argument.
+    
+    Instead of fixing the comparison in virtio_queue_notify(), move the
+    comparison to the virtio bindings (just like VIRTIO_PCI_QUEUE_SEL) where
+    we have a uint32_t value and can avoid ever calling into common virtio
+    code if the virtqueue number is invalid.
+    
+    Signed-off-by: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com>
+    Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
+    Backported-to-0.12-by: Michael Tokarev <m...@tls.msk.ru>
+
+--- a/hw/syborg_virtio.c
++++ b/hw/syborg_virtio.c
+@@ -145,7 +145,9 @@ static void syborg_virtio_writel(void *o
+             vdev->queue_sel = value;
+         break;
+     case SYBORG_VIRTIO_QUEUE_NOTIFY:
+-        virtio_queue_notify(vdev, value);
++        if (value < VIRTIO_PCI_QUEUE_MAX) {
++            virtio_queue_notify(vdev, value);
++        }
+         break;
+     case SYBORG_VIRTIO_STATUS:
+         vdev->status = value & 0xFF;
+--- a/hw/virtio-pci.c
++++ b/hw/virtio-pci.c
+@@ -197,7 +197,9 @@ static void virtio_ioport_write(void *op
+             vdev->queue_sel = val;
+         break;
+     case VIRTIO_PCI_QUEUE_NOTIFY:
+-        virtio_queue_notify(vdev, val);
++        if (val < VIRTIO_PCI_QUEUE_MAX) {
++            virtio_queue_notify(vdev, val);
++        }
+         break;
+     case VIRTIO_PCI_STATUS:
+         vdev->status = val & 0xFF;
+--- a/hw/virtio.c
++++ b/hw/virtio.c
+@@ -558,7 +558,7 @@ int virtio_queue_get_num(VirtIODevice *v
+ 
+ void virtio_queue_notify(VirtIODevice *vdev, int n)
+ {
+-    if (n < VIRTIO_PCI_QUEUE_MAX && vdev->vq[n].vring.desc) {
++    if (vdev->vq[n].vring.desc) {
+         vdev->vq[n].handle_output(vdev, &vdev->vq[n]);
+     }
+ }

Reply via email to