diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-08-26 17:45:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-08-26 17:45:09 +0100 |
commit | 47c9dfee808f9455d732aea7c4390ad0972bbd84 (patch) | |
tree | 4daeb2012b1d63f9b1e0b63301f2be40d67511ae | |
parent | 7df9671989c1cfa693764f9ae6349324b2ada02a (diff) | |
parent | eb8934b0418b3b1d125edddc4fc334a54334a49b (diff) | |
download | hqemu-47c9dfee808f9455d732aea7c4390ad0972bbd84.zip hqemu-47c9dfee808f9455d732aea7c4390ad0972bbd84.tar.gz |
Merge remote-tracking branch 'remotes/kraxel/tags/pull-cve-2015-5225-20150826-1' into staging
vnc: fix memory corruption (CVE-2015-5225)
# gpg: Signature made Wed 26 Aug 2015 17:37:21 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
* remotes/kraxel/tags/pull-cve-2015-5225-20150826-1:
vnc: fix memory corruption (CVE-2015-5225)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | ui/vnc.c | 15 |
1 files changed, 10 insertions, 5 deletions
@@ -2872,7 +2872,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd) pixman_image_get_width(vd->server)); int height = MIN(pixman_image_get_height(vd->guest.fb), pixman_image_get_height(vd->server)); - int cmp_bytes, server_stride, min_stride, guest_stride, y = 0; + int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0; uint8_t *guest_row0 = NULL, *server_row0; VncState *vs; int has_dirty = 0; @@ -2891,17 +2891,21 @@ static int vnc_refresh_server_surface(VncDisplay *vd) * Update server dirty map. */ server_row0 = (uint8_t *)pixman_image_get_data(vd->server); - server_stride = guest_stride = pixman_image_get_stride(vd->server); + server_stride = guest_stride = guest_ll = + pixman_image_get_stride(vd->server); cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES, server_stride); if (vd->guest.format != VNC_SERVER_FB_FORMAT) { int width = pixman_image_get_width(vd->server); tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width); } else { + int guest_bpp = + PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb)); guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb); guest_stride = pixman_image_get_stride(vd->guest.fb); + guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8); } - min_stride = MIN(server_stride, guest_stride); + line_bytes = MIN(server_stride, guest_ll); for (;;) { int x; @@ -2932,9 +2936,10 @@ static int vnc_refresh_server_surface(VncDisplay *vd) if (!test_and_clear_bit(x, vd->guest.dirty[y])) { continue; } - if ((x + 1) * cmp_bytes > min_stride) { - _cmp_bytes = min_stride - x * cmp_bytes; + if ((x + 1) * cmp_bytes > line_bytes) { + _cmp_bytes = line_bytes - x * cmp_bytes; } + assert(_cmp_bytes >= 0); if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) { continue; } |