673fe7b
From 4299b90e9ba9ce5ca9024572804ba751aa1a7e70 Mon Sep 17 00:00:00 2001
673fe7b
From: Prasad J Pandit <pjp@fedoraproject.org>
673fe7b
Date: Tue, 18 Oct 2016 13:15:17 +0530
673fe7b
Subject: [PATCH] display: cirrus: check vga bits per pixel(bpp) value
673fe7b
673fe7b
In Cirrus CLGD 54xx VGA Emulator, if cirrus graphics mode is VGA,
673fe7b
'cirrus_get_bpp' returns zero(0), which could lead to a divide
673fe7b
by zero error in while copying pixel data. The same could occur
673fe7b
via blit pitch values. Add check to avoid it.
673fe7b
673fe7b
Reported-by: Huawei PSIRT <psirt@huawei.com>
673fe7b
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
673fe7b
Message-id: 1476776717-24807-1-git-send-email-ppandit@redhat.com
673fe7b
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
673fe7b
---
673fe7b
 hw/cirrus_vga.c |   14 ++++++++++----
673fe7b
 1 files changed, 10 insertions(+), 4 deletions(-)
673fe7b
673fe7b
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
673fe7b
index 3d712d5..bdb092e 100644
673fe7b
--- a/hw/cirrus_vga.c
673fe7b
+++ b/hw/cirrus_vga.c
673fe7b
@@ -272,6 +272,9 @@ static void cirrus_update_memory_access(CirrusVGAState *s);
673fe7b
 static bool blit_region_is_unsafe(struct CirrusVGAState *s,
673fe7b
                                   int32_t pitch, int32_t addr)
673fe7b
 {
673fe7b
+    if (!pitch) {
673fe7b
+        return true;
673fe7b
+    }
673fe7b
     if (pitch < 0) {
673fe7b
         int64_t min = addr
e7faf00
             + ((int64_t)s->cirrus_blt_height - 1) * pitch
673fe7b
@@ -715,7 +718,7 @@ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
673fe7b
                                             s->cirrus_addr_mask));
673fe7b
 }
673fe7b
 
673fe7b
-static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
673fe7b
+static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
673fe7b
 {
673fe7b
     int sx = 0, sy = 0;
673fe7b
     int dx = 0, dy = 0;
673fe7b
@@ -729,6 +732,9 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
673fe7b
         int width, height;
673fe7b
 
673fe7b
         depth = s->get_bpp((VGAState *)s) / 8;
673fe7b
+        if (!depth) {
673fe7b
+            return 0;
673fe7b
+        }
673fe7b
         s->get_resolution((VGAState *)s, &width, &height);
673fe7b
 
673fe7b
         /* extra x, y */
673fe7b
@@ -783,6 +789,8 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
673fe7b
     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
673fe7b
 				s->cirrus_blt_dstpitch, s->cirrus_blt_width,
673fe7b
 				s->cirrus_blt_height);
673fe7b
+
673fe7b
+    return 1;
673fe7b
 }
673fe7b
 
673fe7b
 static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
673fe7b
@@ -790,11 +798,9 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
673fe7b
     if (blit_is_unsafe(s))
673fe7b
         return 0;
673fe7b
 
673fe7b
-    cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
673fe7b
+    return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->start_addr,
673fe7b
             s->cirrus_blt_srcaddr - s->start_addr,
673fe7b
             s->cirrus_blt_width, s->cirrus_blt_height);
673fe7b
-
673fe7b
-    return 1;
673fe7b
 }
673fe7b
 
673fe7b
 /***************************************
673fe7b
-- 
673fe7b
1.7.0.4
673fe7b