Commit 47c9dfee authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 7df96719 eb8934b0
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -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;
            }