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