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