From f61d82c2dfe02a60642a76e8f0034a0244eef2bf Mon Sep 17 00:00:00 2001 From: Gonglei Date: Mon, 12 May 2014 15:10:38 +0800 Subject: [PATCH 1/3] cirrus_vga: adding sanity check for vram size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit when configure a invalid vram size for cirrus card, such as less 2 MB, which will crash qemu. Follow the real hardware, the cirrus card has 4 MB video memory. Also for backward compatibility, accept 8 MB and 16 MB vram size. Signed-off-by: Gonglei Reviewed-by: Andreas Färber Signed-off-by: Gerd Hoffmann --- hw/display/cirrus_vga.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 6fbe39d5d4..52d039e9bc 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2911,6 +2911,14 @@ static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp) ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev); VGACommonState *s = &d->cirrus_vga.vga; + /* follow real hardware, cirrus card emulated has 4 MB video memory. + Also accept 8 MB/16 MB for backward compatibility. */ + if (s->vram_size_mb != 4 && s->vram_size_mb != 8 && + s->vram_size_mb != 16) { + error_setg(errp, "Invalid cirrus_vga ram size '%u'", + s->vram_size_mb); + return; + } vga_common_init(s, OBJECT(dev), true); cirrus_init_common(&d->cirrus_vga, OBJECT(dev), CIRRUS_ID_CLGD5430, 0, isa_address_space(isadev), @@ -2957,6 +2965,14 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); int16_t device_id = pc->device_id; + /* follow real hardware, cirrus card emulated has 4 MB video memory. + Also accept 8 MB/16 MB for backward compatibility. */ + if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 && + s->vga.vram_size_mb != 16) { + error_report("Invalid cirrus_vga ram size '%u'", + s->vga.vram_size_mb); + return -1; + } /* setup VGA */ vga_common_init(&s->vga, OBJECT(dev), true); cirrus_init_common(s, OBJECT(dev), device_id, 1, pci_address_space(dev), From e8ee4b68bed36471b014c23209299c84b8d4a01b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 2 Jul 2014 20:32:08 +1000 Subject: [PATCH 2/3] cirrus: Fix build of debug code Use PRIu64 to print uint64_t Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann --- hw/display/cirrus_vga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 52d039e9bc..db330e9548 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2059,7 +2059,7 @@ static void cirrus_vga_mem_write(void *opaque, } } else { #ifdef DEBUG_CIRRUS - printf("cirrus: mem_writeb " TARGET_FMT_plx " value %02x\n", addr, + printf("cirrus: mem_writeb " TARGET_FMT_plx " value 0x%02" PRIu64 "\n", addr, mem_value); #endif } @@ -2594,7 +2594,7 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, break; case 0x3c5: #ifdef DEBUG_VGA_REG - printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); + printf("vga: write SR%x = 0x%02" PRIu64 "\n", s->sr_index, val); #endif cirrus_vga_write_sr(c, val); break; @@ -2619,7 +2619,7 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, break; case 0x3cf: #ifdef DEBUG_VGA_REG - printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); + printf("vga: write GR%x = 0x%02" PRIu64 "\n", s->gr_index, val); #endif cirrus_vga_write_gr(c, s->gr_index, val); break; @@ -2630,7 +2630,7 @@ static void cirrus_vga_ioport_write(void *opaque, hwaddr addr, uint64_t val, case 0x3b5: case 0x3d5: #ifdef DEBUG_VGA_REG - printf("vga: write CR%x = 0x%02x\n", s->cr_index, val); + printf("vga: write CR%x = 0x%02"PRIu64"\n", s->cr_index, val); #endif cirrus_vga_write_cr(c, val); break; From d16136d22af0fcf0d651de04c9e3cbc7137cc6f9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2014 10:32:34 +1000 Subject: [PATCH 3/3] cirrus: Fix host CPU blits Commit b2eb849d4b1fdb6f35d5c46958c7f703cf64cfef "CVE-2007-1320 - Cirrus LGD-54XX "bitblt" heap overflow" broke cpu to video blits. When the ROP function is called from cirrus_bitblt_cputovideo_next(), we pass 0 for the pitch but only operate on one line at a time. The added test was tripping because after the initial substraction, the pitch becomes negative. Make the test only trip when the height is larger than one (ie. the pitch is actually used). This fixes HW cursor support in Windows NT4.0 (which otherwise was a white rectangle) and general display of icons in that OS when using 8bpp mode. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann --- hw/display/cirrus_vga_rop.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/display/cirrus_vga_rop.h b/hw/display/cirrus_vga_rop.h index 9c7bb09286..0925a009fe 100644 --- a/hw/display/cirrus_vga_rop.h +++ b/hw/display/cirrus_vga_rop.h @@ -52,8 +52,7 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s, dstpitch -= bltwidth; srcpitch -= bltwidth; - if (dstpitch < 0 || srcpitch < 0) { - /* is 0 valid? srcpitch == 0 could be useful */ + if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) { return; }