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

Bug#626003: pu: package qemu-kvm/0.12.5+dfsg-5+squeeze2



09.05.2011 22:10, Philipp Kern wrote:
> On Mon, May 09, 2011 at 12:44:54PM +0400, Michael Tokarev wrote:
>> I forgot to show a debdiff for the request.
> 
> Please debdiff the source, not the resulting binary.  And yeah, I marked this
> mail as to-do while on the road because the diff was actually missing.  If you
> can just attach it to a reply that would be quite helpful.

Here it goes.  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,16 @@
+qemu-kvm (0.12.5+dfsg-5+squeeze2) stable; urgency=low
+
+  * cirrus_vga:fix-division-by-0-for-color-expansion-rop-92d675d1c1.diff
+   (fix from upstream) - fixes division by zero with some guests
+   like WinNT 4.0 and WinME.
+  * fix-vnc-zlib-overflow.diff (backport from 0.14) (closes: #616159)
+  * qdev-dont-hw_error-in-qdev_init_nofail-bd6c9a61.diff -
+    don't abort but exit on user errors (closes: #619452)
+  * fix transitional kvm package description (closes: #625206)
+  * fix long-standing migration bug on 32bits (closes: #625571)
+
+ -- Michael Tokarev <mjt@tls.msk.ru>  Sat, 07 May 2011 21:18:15 +0400
+
 qemu-kvm (0.12.5+dfsg-5+squeeze1) stable-security; urgency=high
 
   * fix CVE-2011-0011: Setting VNC password to empty string
diff -u qemu-kvm-0.12.5+dfsg/debian/control qemu-kvm-0.12.5+dfsg/debian/control
--- qemu-kvm-0.12.5+dfsg/debian/control
+++ qemu-kvm-0.12.5+dfsg/debian/control
@@ -56,5 +56,5 @@
 Description: dummy transitional package from kvm to qemu-kvm
  This transitional package helps users transition from the kvm package to the
- kvm-qemu package.  Once this package and its dependencies are installed you
+ qemu-kvm package.  Once this package and its dependencies are installed you
  can safely remove it.
 
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
@@ -31,0 +32,4 @@
+cirrus_vga:fix-division-by-0-for-color-expansion-rop-92d675d1c1.diff
+fix-vnc-zlib-overflow.diff
+qdev-dont-hw_error-in-qdev_init_nofail-bd6c9a61.diff
+fix-crash-in-migration-32-bit-51b0c6065a.diff
only in patch2:
unchanged:
--- qemu-kvm-0.12.5+dfsg.orig/debian/patches/cirrus_vga:fix-division-by-0-for-color-expansion-rop-92d675d1c1.diff
+++ qemu-kvm-0.12.5+dfsg/debian/patches/cirrus_vga:fix-division-by-0-for-color-expansion-rop-92d675d1c1.diff
@@ -0,0 +1,100 @@
+commit 92d675d1c1f23f3617e24b63c825074a1d1da44b
+Author: Aurelien Jarno <aurelien@aurel32.net>
+Date:   Tue Jan 4 21:58:24 2011 +0100
+
+    cirrus_vga: fix division by 0 for color expansion rop
+    
+    Commit d85d0d3883f5a567fa2969a0396e42e0a662b3fa introduces a regression
+    with Windows ME that leads to a division by 0 and a crash.
+    
+    It uses the color expansion rop with the source pitch set to 0. This is
+    something allowed, as the manual explicitely says "When the source of
+    color-expand data is display memory, the source pitch is ignored.".
+    
+    This patch fixes this regression by computing sx, sy and others
+    variables only if they are going to be used later, that is for a plain
+    copy ROP. It basically consists in moving code.
+    
+    Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+
+diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
+index 4f5040c..199136c 100644
+--- a/hw/cirrus_vga.c
++++ b/hw/cirrus_vga.c
+@@ -675,43 +675,44 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+ {
+     int sx, sy;
+     int dx, dy;
+-    int width, height;
+     int depth;
+     int notify = 0;
+ 
+-    depth = s->vga.get_bpp(&s->vga) / 8;
+-    s->vga.get_resolution(&s->vga, &width, &height);
+-
+-    /* extra x, y */
+-    sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
+-    sy = (src / ABS(s->cirrus_blt_srcpitch));
+-    dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
+-    dy = (dst / ABS(s->cirrus_blt_dstpitch));
+-
+-    /* normalize width */
+-    w /= depth;
+-
+-    /* if we're doing a backward copy, we have to adjust
+-       our x/y to be the upper left corner (instead of the lower
+-       right corner) */
+-    if (s->cirrus_blt_dstpitch < 0) {
+-	sx -= (s->cirrus_blt_width / depth) - 1;
+-	dx -= (s->cirrus_blt_width / depth) - 1;
+-	sy -= s->cirrus_blt_height - 1;
+-	dy -= s->cirrus_blt_height - 1;
+-    }
++    /* make sure to only copy if it's a plain copy ROP */
++    if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||
++        *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {
+ 
+-    /* are we in the visible portion of memory? */
+-    if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
+-	(sx + w) <= width && (sy + h) <= height &&
+-	(dx + w) <= width && (dy + h) <= height) {
+-	notify = 1;
+-    }
++        int width, height;
++
++        depth = s->vga.get_bpp(&s->vga) / 8;
++        s->vga.get_resolution(&s->vga, &width, &height);
++
++        /* extra x, y */
++        sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;
++        sy = (src / ABS(s->cirrus_blt_srcpitch));
++        dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;
++        dy = (dst / ABS(s->cirrus_blt_dstpitch));
+ 
+-    /* make to sure only copy if it's a plain copy ROP */
+-    if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src &&
+-	*s->cirrus_rop != cirrus_bitblt_rop_bkwd_src)
+-	notify = 0;
++        /* normalize width */
++        w /= depth;
++
++        /* if we're doing a backward copy, we have to adjust
++           our x/y to be the upper left corner (instead of the lower
++           right corner) */
++        if (s->cirrus_blt_dstpitch < 0) {
++            sx -= (s->cirrus_blt_width / depth) - 1;
++            dx -= (s->cirrus_blt_width / depth) - 1;
++            sy -= s->cirrus_blt_height - 1;
++            dy -= s->cirrus_blt_height - 1;
++        }
++
++        /* are we in the visible portion of memory? */
++        if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&
++            (sx + w) <= width && (sy + h) <= height &&
++            (dx + w) <= width && (dy + h) <= height) {
++            notify = 1;
++        }
++    }
+ 
+     /* we have to flush all pending changes so that the copy
+        is generated at the appropriate moment in time */
only in patch2:
unchanged:
--- qemu-kvm-0.12.5+dfsg.orig/debian/patches/fix-crash-in-migration-32-bit-51b0c6065a.diff
+++ qemu-kvm-0.12.5+dfsg/debian/patches/fix-crash-in-migration-32-bit-51b0c6065a.diff
@@ -0,0 +1,109 @@
+Cherry-picked from upstream and backported to 0.12 version,
+added first half of the bugfix for #625571 -- see that
+bugreport for full details.
+	-- mjt
+
+commit 51b0c6065aa6e47a47094d73e24be298a4a7f3a1
+Author: Michael Tokarev <mjt@tls.msk.ru>
+Date:   Tue Apr 26 20:13:49 2011 +0400
+
+    fix crash in migration, 32-bit userspace on 64-bit host
+    
+    This change fixes a long-standing immediate crash (memory corruption
+    and abort in glibc malloc code) in migration on 32bits.
+    
+    The bug is present since this commit:
+    
+      commit 692d9aca97b865b0f7903565274a52606910f129
+      Author: Bruce Rogers <brogers@novell.com>
+      Date:   Wed Sep 23 16:13:18 2009 -0600
+    
+        qemu-kvm: allocate correct size for dirty bitmap
+    
+        The dirty bitmap copied out to userspace is stored in a long array,
+        and gets copied out to userspace accordingly.  This patch accounts
+        for that correctly.  Currently I'm seeing kvm crashing due to writing
+        beyond the end of the alloc'd dirty bitmap memory, because the buffer
+        has the wrong size.
+    
+        Signed-off-by: Bruce Rogers
+        Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+    
+     --- a/qemu-kvm.c
+     +++ b/qemu-kvm.c
+     @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
+     -            buf = qemu_malloc((slots[i].len / 4096 + 7) / 8 + 2);
+     +            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
+                 r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
+    
+    BITMAP_SIZE is now open-coded in that function, like this:
+    
+     size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS), HOST_LONG_BITS) / 8;
+    
+    The problem is that HOST_LONG_BITS in 32bit userspace is 32
+    but it's 64 in 64bit kernel.  So userspace aligns this to
+    32, and kernel to 64, but since no length is passed from
+    userspace to kernel on ioctl, kernel uses its size calculation
+    and copies 4 extra bytes to userspace, corrupting memory.
+    
+    Here's how it looks like during migrate execution:
+    
+    our=20, kern=24
+    our=4, kern=8
+    ...
+    our=4, kern=8
+    our=4064, kern=4064
+    our=512, kern=512
+    our=4, kern=8
+    our=20, kern=24
+    our=4, kern=8
+    ...
+    our=4, kern=8
+    our=4064, kern=4064
+    *** glibc detected *** ./x86_64-softmmu/qemu-system-x86_64: realloc(): invalid next size: 0x08f20528 ***
+    
+    (our is userspace size above, kern is the size as calculated
+    by the kernel).
+    
+    Fix this by always aligning to 64 in a hope that no platform will
+    have sizeof(long)>8 any time soon, and add a comment describing it
+    all.  It's a small price to pay for bad kernel design.
+    
+    Alternatively it's possible to fix that in the kernel by using
+    different size calculation depending on the current process.
+    But this becomes quite ugly.
+    
+    Special thanks goes to Stefan Hajnoczi for spotting the fundamental
+    cause of the issue, and to Alexander Graf for his support in #qemu.
+    
+    Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+    CC: Bruce Rogers <brogers@novell.com>
+    Signed-off-by: Avi Kivity <avi@redhat.com>
+
+Index: debian/kvm-all.c
+===================================================================
+--- debian.orig/kvm-all.c	2011-05-04 17:59:08.350264734 +0400
++++ debian/kvm-all.c	2011-05-04 17:59:16.497669534 +0400
+@@ -312,7 +312,7 @@
+             break;
+         }
+ 
+-        size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
++        size = BITMAP_SIZE(mem->memory_size);
+         if (!d.dirty_bitmap) {
+             d.dirty_bitmap = qemu_malloc(size);
+         } else if (size > allocated_size) {
+Index: debian/qemu-kvm.h
+===================================================================
+--- debian.orig/qemu-kvm.h	2011-05-04 17:59:13.256049613 +0400
++++ debian/qemu-kvm.h	2011-05-04 17:59:16.497669534 +0400
+@@ -1024,7 +1024,8 @@
+ 
+ #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
+ #ifndef QEMU_KVM_NO_CPU
+-#define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)
++/*mjt: see commit 51b0c6065aa6e47a47094d73e24be298a4a7f3a1 */
++#define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), /*HOST_LONG_BITS*/ 64) / 8)
+ #endif
+ 
+ #ifdef CONFIG_KVM
only in patch2:
unchanged:
--- qemu-kvm-0.12.5+dfsg.orig/debian/patches/qdev-dont-hw_error-in-qdev_init_nofail-bd6c9a61.diff
+++ qemu-kvm-0.12.5+dfsg/debian/patches/qdev-dont-hw_error-in-qdev_init_nofail-bd6c9a61.diff
@@ -0,0 +1,36 @@
+Cherry-picked from upstream 0.14.  There we use error_report()
+routine which does not exist in 0.12, so change it to qemu_error().
+	-- mjt
+
+commit bd6c9a617d969752c9d3663f6ad29ae6d6d6c402
+Author: Markus Armbruster <armbru@redhat.com>
+Date:   Thu May 27 21:23:08 2010 +0200
+
+    qdev: Don't hw_error() in qdev_init_nofail()
+    
+    Some of the failures are internal errors, and hw_error() is okay then.
+    But the common way to fail is bad user input, e.g. -global
+    isa-fdc.driveA=foo where drive foo has an unsupported rerror value.
+    
+    exit(1) instead.
+    
+    Signed-off-by: Markus Armbruster <armbru@redhat.com>
+    Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+
+diff --git a/hw/qdev.c b/hw/qdev.c
+index 61f999c..00ceada 100644
+--- a/hw/qdev.c
++++ b/hw/qdev.c
+@@ -326,8 +326,10 @@ void qdev_init_nofail(DeviceState *dev)
+ {
+     DeviceInfo *info = dev->info;
+ 
+-    if (qdev_init(dev) < 0)
+-        hw_error("Initialization of device %s failed\n", info->name);
++    if (qdev_init(dev) < 0) {
++        qemu_error("Initialization of device %s failed\n", info->name);
++        exit(1);
++    }
+ }
+ 
+ /* Unlink device from bus and free the structure.  */
only in patch2:
unchanged:
--- qemu-kvm-0.12.5+dfsg.orig/debian/patches/fix-vnc-zlib-overflow.diff
+++ qemu-kvm-0.12.5+dfsg/debian/patches/fix-vnc-zlib-overflow.diff
@@ -0,0 +1,44 @@
+This is a backport from 0.14.
+
+fix 2Gb integer overflow in in VNC tight and zlib encodings
+
+As found by Roland Dreier <roland@purestorage.com> (excellent
+catch!), when amount of VNC compressed data produced by zlib
+and sent to client exceeds 2Gb, integer overflow occurs because
+currently, we calculate amount of data produced at each step by
+comparing saved total_out with new total_out, and total_out is
+something which grows without bounds.  Compare it with previous
+avail_out instead of total_out, and leave total_out alone.
+
+There, there's no actual need to save previous_out value, since
+capacity-offset (which is how that value is calculated) stays
+the same so it can be recalculated again after call to deflate(),
+but whole thing becomes less readable this way.
+
+Reported-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+
+
+diff --git a/vnc.c b/vnc.c
+index 8566a4b..d09de3e 100644
+--- a/vnc.c
++++ b/vnc.c
+@@ -746,8 +746,8 @@ static int vnc_zlib_stop(VncState *vs, int stream_id)
+     zstream->avail_in = vs->zlib.offset;
+     zstream->next_out = vs->output.buffer + vs->output.offset;
+     zstream->avail_out = vs->output.capacity - vs->output.offset;
++    previous_out = zstream->avail_out;
+     zstream->data_type = Z_BINARY;
+-    previous_out = zstream->total_out;
+ 
+     // start encoding
+     if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
+@@ -756,7 +756,7 @@ static int vnc_zlib_stop(VncState *vs, int stream_id)
+     }
+ 
+     vs->output.offset = vs->output.capacity - zstream->avail_out;
+-    return zstream->total_out - previous_out;
++    return previous_out - zstream->avail_out;
+ }
+ 
+ static void send_framebuffer_update_zlib(VncState *vs, int x, int y, int w, int h)

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: