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]); + } + }