qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/6] Vga 20170913 patches
@ 2017-09-13  7:41 Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen) Gerd Hoffmann
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The following changes since commit 223cd0e13f2e46078d7b573f0b8402bfbee339be:

  Merge remote-tracking branch 'remotes/elmarco/tags/tidy-pull-request' into staging (2017-08-31 15:52:43 +0100)

are available in the git repository at:

  git://git.kraxel.org/qemu tags/vga-20170913-pull-request

for you to fetch changes up to 79d16c21a565927943486b26789caa62413ff371:

  virtio-gpu: don't clear QemuUIInfo information on reset (2017-09-13 09:39:32 +0200)

----------------------------------------------------------------
vga: bugfixes.
qxl: chunked cursor support.

----------------------------------------------------------------

Dr. David Alan Gilbert (1):
  vga/migration: Update memory map in post_load

Gerd Hoffmann (5):
  vga: fix display update region calculation (split screen)
  vga: stop passing pointers to vga_draw_line* functions
  qxl: drop mono cursor support
  qxl: add support for chunked cursors.
  virtio-gpu: don't clear QemuUIInfo information on reset

 hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++---------------------
 hw/display/vga_int.h     |   1 +
 hw/display/qxl-render.c  |  45 +++++++----
 hw/display/vga.c         |  16 +++-
 hw/display/virtio-gpu.c  |  12 ---
 5 files changed, 152 insertions(+), 124 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen)
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-10-10 12:41   ` Peter Maydell
  2017-09-13  7:41 ` [Qemu-devel] [PULL 2/6] vga: stop passing pointers to vga_draw_line* functions Gerd Hoffmann
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, P J P

vga display update mis-calculated the region for the dirty bitmap
snapshot in case split screen mode is used.  This can trigger an
assert in cpu_physical_memory_snapshot_get_dirty().

Impact:  DoS for privileged guest users.

Fixes: CVE-2017-13673
Fixes: fec5e8c92becad223df9d972770522f64aafdb72
Cc: P J P <ppandit@redhat.com>
Reported-by: David Buchanan <d@vidbuchanan.co.uk>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828123307.15392-1-kraxel@redhat.com
---
 hw/display/vga.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 3433102ef3..ad7a46563c 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1628,9 +1628,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     y1 = 0;
 
     if (!full_update) {
+        ram_addr_t region_start = addr1;
+        ram_addr_t region_end = addr1 + line_offset * height;
         vga_sync_dirty_bitmap(s);
-        snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
-                                                      line_offset * height,
+        if (s->line_compare < height) {
+            /* split screen mode */
+            region_start = 0;
+        }
+        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
+                                                      region_end - region_start,
                                                       DIRTY_MEMORY_VGA);
     }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 2/6] vga: stop passing pointers to vga_draw_line* functions
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen) Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 3/6] qxl: drop mono cursor support Gerd Hoffmann
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, P J P

Instead pass around the address (aka offset into vga memory).
Add vga_read_* helper functions which apply vbe_size_mask to
the address, to make sure the address stays within the valid
range, similar to the cirrus blitter fixes (commits ffaf857778
and 026aeffcb4).

Impact:  DoS for privileged guest users.  qemu crashes with
a segfault, when hitting the guard page after vga memory
allocation, while reading vga memory for display updates.

Fixes: CVE-2017-13672
Cc: P J P <ppandit@redhat.com>
Reported-by: David Buchanan <d@vidbuchanan.co.uk>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828122906.18993-1-kraxel@redhat.com
---
 hw/display/vga-helpers.h | 202 ++++++++++++++++++++++++++---------------------
 hw/display/vga_int.h     |   1 +
 hw/display/vga.c         |   5 +-
 3 files changed, 114 insertions(+), 94 deletions(-)

diff --git a/hw/display/vga-helpers.h b/hw/display/vga-helpers.h
index 94f6de2046..5a752b3f9e 100644
--- a/hw/display/vga-helpers.h
+++ b/hw/display/vga-helpers.h
@@ -95,20 +95,46 @@ static void vga_draw_glyph9(uint8_t *d, int linesize,
     } while (--h);
 }
 
+static inline uint8_t vga_read_byte(VGACommonState *vga, uint32_t addr)
+{
+    return vga->vram_ptr[addr & vga->vbe_size_mask];
+}
+
+static inline uint16_t vga_read_word_le(VGACommonState *vga, uint32_t addr)
+{
+    uint32_t offset = addr & vga->vbe_size_mask & ~1;
+    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+    return lduw_le_p(ptr);
+}
+
+static inline uint16_t vga_read_word_be(VGACommonState *vga, uint32_t addr)
+{
+    uint32_t offset = addr & vga->vbe_size_mask & ~1;
+    uint16_t *ptr = (uint16_t *)(vga->vram_ptr + offset);
+    return lduw_be_p(ptr);
+}
+
+static inline uint32_t vga_read_dword_le(VGACommonState *vga, uint32_t addr)
+{
+    uint32_t offset = addr & vga->vbe_size_mask & ~3;
+    uint32_t *ptr = (uint32_t *)(vga->vram_ptr + offset);
+    return ldl_le_p(ptr);
+}
+
 /*
  * 4 color mode
  */
-static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
-                           const uint8_t *s, int width)
+static void vga_draw_line2(VGACommonState *vga, uint8_t *d,
+                           uint32_t addr, int width)
 {
     uint32_t plane_mask, *palette, data, v;
     int x;
 
-    palette = s1->last_palette;
-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+    palette = vga->last_palette;
+    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
     width >>= 3;
     for(x = 0; x < width; x++) {
-        data = ((uint32_t *)s)[0];
+        data = vga_read_dword_le(vga, addr);
         data &= plane_mask;
         v = expand2[GET_PLANE(data, 0)];
         v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -124,7 +150,7 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
         ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
         ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
         d += 32;
-        s += 4;
+        addr += 4;
     }
 }
 
@@ -134,17 +160,17 @@ static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
 /*
  * 4 color mode, dup2 horizontal
  */
-static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
-                             const uint8_t *s, int width)
+static void vga_draw_line2d2(VGACommonState *vga, uint8_t *d,
+                             uint32_t addr, int width)
 {
     uint32_t plane_mask, *palette, data, v;
     int x;
 
-    palette = s1->last_palette;
-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+    palette = vga->last_palette;
+    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
     width >>= 3;
     for(x = 0; x < width; x++) {
-        data = ((uint32_t *)s)[0];
+        data = vga_read_dword_le(vga, addr);
         data &= plane_mask;
         v = expand2[GET_PLANE(data, 0)];
         v |= expand2[GET_PLANE(data, 2)] << 2;
@@ -160,24 +186,24 @@ static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
         d += 64;
-        s += 4;
+        addr += 4;
     }
 }
 
 /*
  * 16 color mode
  */
-static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
-                           const uint8_t *s, int width)
+static void vga_draw_line4(VGACommonState *vga, uint8_t *d,
+                           uint32_t addr, int width)
 {
     uint32_t plane_mask, data, v, *palette;
     int x;
 
-    palette = s1->last_palette;
-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+    palette = vga->last_palette;
+    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
     width >>= 3;
     for(x = 0; x < width; x++) {
-        data = ((uint32_t *)s)[0];
+        data = vga_read_dword_le(vga, addr);
         data &= plane_mask;
         v = expand4[GET_PLANE(data, 0)];
         v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -192,24 +218,24 @@ static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
         ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
         ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
         d += 32;
-        s += 4;
+        addr += 4;
     }
 }
 
 /*
  * 16 color mode, dup2 horizontal
  */
-static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
-                             const uint8_t *s, int width)
+static void vga_draw_line4d2(VGACommonState *vga, uint8_t *d,
+                             uint32_t addr, int width)
 {
     uint32_t plane_mask, data, v, *palette;
     int x;
 
-    palette = s1->last_palette;
-    plane_mask = mask16[s1->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
+    palette = vga->last_palette;
+    plane_mask = mask16[vga->ar[VGA_ATC_PLANE_ENABLE] & 0xf];
     width >>= 3;
     for(x = 0; x < width; x++) {
-        data = ((uint32_t *)s)[0];
+        data = vga_read_dword_le(vga, addr);
         data &= plane_mask;
         v = expand4[GET_PLANE(data, 0)];
         v |= expand4[GET_PLANE(data, 1)] << 1;
@@ -224,7 +250,7 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
         d += 64;
-        s += 4;
+        addr += 4;
     }
 }
 
@@ -233,21 +259,21 @@ static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
  *
  * XXX: add plane_mask support (never used in standard VGA modes)
  */
-static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
-                             const uint8_t *s, int width)
+static void vga_draw_line8d2(VGACommonState *vga, uint8_t *d,
+                             uint32_t addr, int width)
 {
     uint32_t *palette;
     int x;
 
-    palette = s1->last_palette;
+    palette = vga->last_palette;
     width >>= 3;
     for(x = 0; x < width; x++) {
-        PUT_PIXEL2(d, 0, palette[s[0]]);
-        PUT_PIXEL2(d, 1, palette[s[1]]);
-        PUT_PIXEL2(d, 2, palette[s[2]]);
-        PUT_PIXEL2(d, 3, palette[s[3]]);
+        PUT_PIXEL2(d, 0, palette[vga_read_byte(vga, addr + 0)]);
+        PUT_PIXEL2(d, 1, palette[vga_read_byte(vga, addr + 1)]);
+        PUT_PIXEL2(d, 2, palette[vga_read_byte(vga, addr + 2)]);
+        PUT_PIXEL2(d, 3, palette[vga_read_byte(vga, addr + 3)]);
         d += 32;
-        s += 4;
+        addr += 4;
     }
 }
 
@@ -256,63 +282,63 @@ static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
  *
  * XXX: add plane_mask support (never used in standard VGA modes)
  */
-static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
-                           const uint8_t *s, int width)
+static void vga_draw_line8(VGACommonState *vga, uint8_t *d,
+                           uint32_t addr, int width)
 {
     uint32_t *palette;
     int x;
 
-    palette = s1->last_palette;
+    palette = vga->last_palette;
     width >>= 3;
     for(x = 0; x < width; x++) {
-        ((uint32_t *)d)[0] = palette[s[0]];
-        ((uint32_t *)d)[1] = palette[s[1]];
-        ((uint32_t *)d)[2] = palette[s[2]];
-        ((uint32_t *)d)[3] = palette[s[3]];
-        ((uint32_t *)d)[4] = palette[s[4]];
-        ((uint32_t *)d)[5] = palette[s[5]];
-        ((uint32_t *)d)[6] = palette[s[6]];
-        ((uint32_t *)d)[7] = palette[s[7]];
+        ((uint32_t *)d)[0] = palette[vga_read_byte(vga, addr + 0)];
+        ((uint32_t *)d)[1] = palette[vga_read_byte(vga, addr + 1)];
+        ((uint32_t *)d)[2] = palette[vga_read_byte(vga, addr + 2)];
+        ((uint32_t *)d)[3] = palette[vga_read_byte(vga, addr + 3)];
+        ((uint32_t *)d)[4] = palette[vga_read_byte(vga, addr + 4)];
+        ((uint32_t *)d)[5] = palette[vga_read_byte(vga, addr + 5)];
+        ((uint32_t *)d)[6] = palette[vga_read_byte(vga, addr + 6)];
+        ((uint32_t *)d)[7] = palette[vga_read_byte(vga, addr + 7)];
         d += 32;
-        s += 8;
+        addr += 8;
     }
 }
 
 /*
  * 15 bit color
  */
-static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line15_le(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t v, r, g, b;
 
     w = width;
     do {
-        v = lduw_le_p((void *)s);
+        v = vga_read_word_le(vga, addr);
         r = (v >> 7) & 0xf8;
         g = (v >> 2) & 0xf8;
         b = (v << 3) & 0xf8;
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 2;
+        addr += 2;
         d += 4;
     } while (--w != 0);
 }
 
-static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line15_be(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t v, r, g, b;
 
     w = width;
     do {
-        v = lduw_be_p((void *)s);
+        v = vga_read_word_be(vga, addr);
         r = (v >> 7) & 0xf8;
         g = (v >> 2) & 0xf8;
         b = (v << 3) & 0xf8;
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 2;
+        addr += 2;
         d += 4;
     } while (--w != 0);
 }
@@ -320,38 +346,38 @@ static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
 /*
  * 16 bit color
  */
-static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line16_le(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t v, r, g, b;
 
     w = width;
     do {
-        v = lduw_le_p((void *)s);
+        v = vga_read_word_le(vga, addr);
         r = (v >> 8) & 0xf8;
         g = (v >> 3) & 0xfc;
         b = (v << 3) & 0xf8;
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 2;
+        addr += 2;
         d += 4;
     } while (--w != 0);
 }
 
-static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line16_be(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t v, r, g, b;
 
     w = width;
     do {
-        v = lduw_be_p((void *)s);
+        v = vga_read_word_be(vga, addr);
         r = (v >> 8) & 0xf8;
         g = (v >> 3) & 0xfc;
         b = (v << 3) & 0xf8;
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 2;
+        addr += 2;
         d += 4;
     } while (--w != 0);
 }
@@ -359,36 +385,36 @@ static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
 /*
  * 24 bit color
  */
-static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line24_le(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t r, g, b;
 
     w = width;
     do {
-        b = s[0];
-        g = s[1];
-        r = s[2];
+        b = vga_read_byte(vga, addr + 0);
+        g = vga_read_byte(vga, addr + 1);
+        r = vga_read_byte(vga, addr + 2);
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 3;
+        addr += 3;
         d += 4;
     } while (--w != 0);
 }
 
-static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line24_be(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
     int w;
     uint32_t r, g, b;
 
     w = width;
     do {
-        r = s[0];
-        g = s[1];
-        b = s[2];
+        r = vga_read_byte(vga, addr + 0);
+        g = vga_read_byte(vga, addr + 1);
+        b = vga_read_byte(vga, addr + 2);
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 3;
+        addr += 3;
         d += 4;
     } while (--w != 0);
 }
@@ -396,44 +422,36 @@ static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
 /*
  * 32 bit color
  */
-static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line32_le(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
-#ifndef HOST_WORDS_BIGENDIAN
-    memcpy(d, s, width * 4);
-#else
     int w;
     uint32_t r, g, b;
 
     w = width;
     do {
-        b = s[0];
-        g = s[1];
-        r = s[2];
+        b = vga_read_byte(vga, addr + 0);
+        g = vga_read_byte(vga, addr + 1);
+        r = vga_read_byte(vga, addr + 2);
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 4;
+        addr += 4;
         d += 4;
     } while (--w != 0);
-#endif
 }
 
-static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
-                               const uint8_t *s, int width)
+static void vga_draw_line32_be(VGACommonState *vga, uint8_t *d,
+                               uint32_t addr, int width)
 {
-#ifdef HOST_WORDS_BIGENDIAN
-    memcpy(d, s, width * 4);
-#else
     int w;
     uint32_t r, g, b;
 
     w = width;
     do {
-        r = s[1];
-        g = s[2];
-        b = s[3];
+        r = vga_read_byte(vga, addr + 1);
+        g = vga_read_byte(vga, addr + 2);
+        b = vga_read_byte(vga, addr + 3);
         ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
-        s += 4;
+        addr += 4;
         d += 4;
     } while (--w != 0);
-#endif
 }
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index dd6c958da3..ad34a1f048 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -94,6 +94,7 @@ typedef struct VGACommonState {
     uint32_t vram_size;
     uint32_t vram_size_mb; /* property */
     uint32_t vbe_size;
+    uint32_t vbe_size_mask;
     uint32_t latch;
     bool has_chain4_alias;
     MemoryRegion chain4_alias;
diff --git a/hw/display/vga.c b/hw/display/vga.c
index ad7a46563c..6fc8c8708a 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
 }
 
 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
-                                const uint8_t *s, int width);
+                                uint32_t srcaddr, int width);
 
 #include "vga-helpers.h"
 
@@ -1666,7 +1666,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
             if (y_start < 0)
                 y_start = y;
             if (!(is_buffer_shared(surface))) {
-                vga_draw_line(s, d, s->vram_ptr + addr, width);
+                vga_draw_line(s, d, addr, width);
                 if (s->cursor_draw_line)
                     s->cursor_draw_line(s, d, y);
             }
@@ -2170,6 +2170,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
     if (!s->vbe_size) {
         s->vbe_size = s->vram_size;
     }
+    s->vbe_size_mask = s->vbe_size - 1;
 
     s->is_vbe_vmstate = 1;
     memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 3/6] qxl: drop mono cursor support
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen) Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 2/6] vga: stop passing pointers to vga_draw_line* functions Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 4/6] qxl: add support for chunked cursors Gerd Hoffmann
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The chunk size sanity check in qxl_render_cursor works for
SPICE_CURSOR_TYPE_ALPHA cursors only.  So support for
SPICE_CURSOR_TYPE_MONO cursors must be broken for ages without anyone
noticing.  Most likely it simply isn't used any more by guest drivers.
Drop the dead code.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828123933.30323-2-kraxel@redhat.com
---
 hw/display/qxl-render.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index 9ad9d9e0f5..e1b3f05ecb 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -207,7 +207,6 @@ void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
 static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
 {
     QEMUCursor *c;
-    uint8_t *image, *mask;
     size_t size;
 
     c = cursor_alloc(cursor->header.width, cursor->header.height);
@@ -221,14 +220,6 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
             cursor_print_ascii_art(c, "qxl/alpha");
         }
         break;
-    case SPICE_CURSOR_TYPE_MONO:
-        mask  = cursor->chunk.data;
-        image = mask + cursor_get_mono_bpl(c) * c->width;
-        cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask);
-        if (qxl->debug > 2) {
-            cursor_print_ascii_art(c, "qxl/mono");
-        }
-        break;
     default:
         fprintf(stderr, "%s: not implemented: type %d\n",
                 __FUNCTION__, cursor->header.type);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 4/6] qxl: add support for chunked cursors.
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2017-09-13  7:41 ` [Qemu-devel] [PULL 3/6] qxl: drop mono cursor support Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 5/6] vga/migration: Update memory map in post_load Gerd Hoffmann
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20170828123933.30323-3-kraxel@redhat.com
---
 hw/display/qxl-render.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index e1b3f05ecb..90e0865618 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -204,7 +204,33 @@ void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie)
     g_free(cookie);
 }
 
-static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
+static void qxl_unpack_chunks(void *dest, size_t size, PCIQXLDevice *qxl,
+                              QXLDataChunk *chunk, uint32_t group_id)
+{
+    uint32_t max_chunks = 32;
+    size_t offset = 0;
+    size_t bytes;
+
+    for (;;) {
+        bytes = MIN(size - offset, chunk->data_size);
+        memcpy(dest + offset, chunk->data, bytes);
+        offset += bytes;
+        if (offset == size) {
+            return;
+        }
+        chunk = qxl_phys2virt(qxl, chunk->next_chunk, group_id);
+        if (!chunk) {
+            return;
+        }
+        max_chunks--;
+        if (max_chunks == 0) {
+            return;
+        }
+    }
+}
+
+static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor,
+                              uint32_t group_id)
 {
     QEMUCursor *c;
     size_t size;
@@ -215,7 +241,7 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor)
     switch (cursor->header.type) {
     case SPICE_CURSOR_TYPE_ALPHA:
         size = sizeof(uint32_t) * cursor->header.width * cursor->header.height;
-        memcpy(c->data, cursor->chunk.data, size);
+        qxl_unpack_chunks(c->data, size, qxl, &cursor->chunk, group_id);
         if (qxl->debug > 2) {
             cursor_print_ascii_art(c, "qxl/alpha");
         }
@@ -259,11 +285,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
         if (!cursor) {
             return 1;
         }
-        if (cursor->chunk.data_size != cursor->data_size) {
-            fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__);
-            return 1;
-        }
-        c = qxl_cursor(qxl, cursor);
+        c = qxl_cursor(qxl, cursor, ext->group_id);
         if (c == NULL) {
             c = cursor_builtin_left_ptr();
         }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 5/6] vga/migration: Update memory map in post_load
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2017-09-13  7:41 ` [Qemu-devel] [PULL 4/6] qxl: add support for chunked cursors Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-09-13  7:41 ` [Qemu-devel] [PULL 6/6] virtio-gpu: don't clear QemuUIInfo information on reset Gerd Hoffmann
  2017-09-14 12:43 ` [Qemu-devel] [PULL 0/6] Vga 20170913 patches Peter Maydell
  6 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Dr. David Alan Gilbert, Gerd Hoffmann

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

After migration the chain4 alias mapping added by 80763888 (in 2011)
might be missing, since there's no call to vga_update_memory_access
in the post_load after the registers are updated.  Add it back.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-id: 20170804113329.13609-1-dgilbert@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/vga.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 6fc8c8708a..ed24ef7076 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -2050,6 +2050,7 @@ static int vga_common_post_load(void *opaque, int version_id)
     /* force refresh */
     s->graphic_mode = -1;
     vbe_update_vgaregs(s);
+    vga_update_memory_access(s);
     return 0;
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 6/6] virtio-gpu: don't clear QemuUIInfo information on reset
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2017-09-13  7:41 ` [Qemu-devel] [PULL 5/6] vga/migration: Update memory map in post_load Gerd Hoffmann
@ 2017-09-13  7:41 ` Gerd Hoffmann
  2017-09-14 12:43 ` [Qemu-devel] [PULL 0/6] Vga 20170913 patches Peter Maydell
  6 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2017-09-13  7:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Michael S. Tsirkin

Don't reset window layout information (passed via virtio_gpu_ui_info) on
device reset, so the user interface window layout will be kept intact
over reboots.  The head size and position was commented out already, so
this patch just drops the dead code.  Additionally the enabled head mask
must be kept so multihead setups work properly too.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1460595
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20170906142058.2460-1-kraxel@redhat.com
---
 hw/display/virtio-gpu.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f0761cf18b..622ee300f9 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1195,17 +1195,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
         virtio_gpu_resource_destroy(g, res);
     }
     for (i = 0; i < g->conf.max_outputs; i++) {
-#if 0
-        g->req_state[i].x = 0;
-        g->req_state[i].y = 0;
-        if (i == 0) {
-            g->req_state[0].width = 1024;
-            g->req_state[0].height = 768;
-        } else {
-            g->req_state[i].width = 0;
-            g->req_state[i].height = 0;
-        }
-#endif
         g->scanout[i].resource_id = 0;
         g->scanout[i].width = 0;
         g->scanout[i].height = 0;
@@ -1213,7 +1202,6 @@ static void virtio_gpu_reset(VirtIODevice *vdev)
         g->scanout[i].y = 0;
         g->scanout[i].ds = NULL;
     }
-    g->enabled_output_bitmask = 1;
 
 #ifdef CONFIG_VIRGL
     if (g->use_virgl_renderer) {
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PULL 0/6] Vga 20170913 patches
  2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2017-09-13  7:41 ` [Qemu-devel] [PULL 6/6] virtio-gpu: don't clear QemuUIInfo information on reset Gerd Hoffmann
@ 2017-09-14 12:43 ` Peter Maydell
  6 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2017-09-14 12:43 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers

On 13 September 2017 at 08:41, Gerd Hoffmann <kraxel@redhat.com> wrote:
> The following changes since commit 223cd0e13f2e46078d7b573f0b8402bfbee339be:
>
>   Merge remote-tracking branch 'remotes/elmarco/tags/tidy-pull-request' into staging (2017-08-31 15:52:43 +0100)
>
> are available in the git repository at:
>
>   git://git.kraxel.org/qemu tags/vga-20170913-pull-request
>
> for you to fetch changes up to 79d16c21a565927943486b26789caa62413ff371:
>
>   virtio-gpu: don't clear QemuUIInfo information on reset (2017-09-13 09:39:32 +0200)
>
> ----------------------------------------------------------------
> vga: bugfixes.
> qxl: chunked cursor support.
>

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen)
  2017-09-13  7:41 ` [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen) Gerd Hoffmann
@ 2017-10-10 12:41   ` Peter Maydell
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2017-10-10 12:41 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers, P J P

On 13 September 2017 at 08:41, Gerd Hoffmann <kraxel@redhat.com> wrote:
> vga display update mis-calculated the region for the dirty bitmap
> snapshot in case split screen mode is used.  This can trigger an
> assert in cpu_physical_memory_snapshot_get_dirty().
>
> Impact:  DoS for privileged guest users.
>
> Fixes: CVE-2017-13673
> Fixes: fec5e8c92becad223df9d972770522f64aafdb72
> Cc: P J P <ppandit@redhat.com>
> Reported-by: David Buchanan <d@vidbuchanan.co.uk>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> Message-id: 20170828123307.15392-1-kraxel@redhat.com
> ---
>  hw/display/vga.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/hw/display/vga.c b/hw/display/vga.c
> index 3433102ef3..ad7a46563c 100644
> --- a/hw/display/vga.c
> +++ b/hw/display/vga.c
> @@ -1628,9 +1628,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>      y1 = 0;
>
>      if (!full_update) {
> +        ram_addr_t region_start = addr1;
> +        ram_addr_t region_end = addr1 + line_offset * height;
>          vga_sync_dirty_bitmap(s);
> -        snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
> -                                                      line_offset * height,
> +        if (s->line_compare < height) {
> +            /* split screen mode */
> +            region_start = 0;
> +        }
> +        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,
> +                                                      region_end - region_start,
>                                                        DIRTY_MEMORY_VGA);
>      }

Hi; Coverity complains about this change, that
        ram_addr_t region_end = addr1 + line_offset * height;

is a potential overflow-before-widen because we calculate
line_offset * height as a 32x32 bit multiply and then
assign it to a 64 bit variable, rather than doing a
64 bit multiply. We could shut it up by casting line_offset
to ram_addr_t...

I don't know whether it's actually possible in this case
for the input values to be such that the multiply result
is bigger than 32 bits.

(CID 1381409.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-10-10 12:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-13  7:41 [Qemu-devel] [PULL 0/6] Vga 20170913 patches Gerd Hoffmann
2017-09-13  7:41 ` [Qemu-devel] [PULL 1/6] vga: fix display update region calculation (split screen) Gerd Hoffmann
2017-10-10 12:41   ` Peter Maydell
2017-09-13  7:41 ` [Qemu-devel] [PULL 2/6] vga: stop passing pointers to vga_draw_line* functions Gerd Hoffmann
2017-09-13  7:41 ` [Qemu-devel] [PULL 3/6] qxl: drop mono cursor support Gerd Hoffmann
2017-09-13  7:41 ` [Qemu-devel] [PULL 4/6] qxl: add support for chunked cursors Gerd Hoffmann
2017-09-13  7:41 ` [Qemu-devel] [PULL 5/6] vga/migration: Update memory map in post_load Gerd Hoffmann
2017-09-13  7:41 ` [Qemu-devel] [PULL 6/6] virtio-gpu: don't clear QemuUIInfo information on reset Gerd Hoffmann
2017-09-14 12:43 ` [Qemu-devel] [PULL 0/6] Vga 20170913 patches Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).