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