rpms/kvm/F-8 kvm-cirrus-bitblt-overflow.patch, NONE, 1.1 kvm.spec, 1.33, 1.34

Glauber Costa (glommer) fedora-extras-commits at redhat.com
Tue May 27 13:27:01 UTC 2008


Author: glommer

Update of /cvs/pkgs/rpms/kvm/F-8
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv29737

Modified Files:
	kvm.spec 
Added Files:
	kvm-cirrus-bitblt-overflow.patch 
Log Message:
* Tue May 27 2008 Glauber Costa <gcosta at redhat.com> - 60-6.fc8
- Fix Cirrus heap overflow vulnerability (#448525)



kvm-cirrus-bitblt-overflow.patch:

--- NEW FILE kvm-cirrus-bitblt-overflow.patch ---
commit b2eb849d4b1fdb6f35d5c46958c7f703cf64cfef
Author: aurel32 <aurel32 at c046a42c-6fe2-441c-8c8c-71466251a162>
Date:   Mon May 5 21:26:31 2008 +0000

    CVE-2007-1320 - Cirrus LGD-54XX "bitblt" heap overflow
    
    I have just noticed that patch for CVE-2007-1320 has never been applied
    to the QEMU CVS. Please find it below.
    
    | Multiple heap-based buffer overflows in the cirrus_invalidate_region
    | function in the Cirrus VGA extension in QEMU 0.8.2, as used in Xen and
    | possibly other products, might allow local users to execute arbitrary
    | code via unspecified vectors related to "attempting to mark
    | non-existent regions as dirty," aka the "bitblt" heap overflow.
    
    
    git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4340 c046a42c-6fe2-441c-8c8c-71466251a162

diff --git a/qemu/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 07e52b0..47acb32 100644
--- a/qemu/hw/cirrus_vga.c
+++ b/qemu/hw/cirrus_vga.c
@@ -220,6 +220,20 @@
 #define CIRRUS_HOOK_NOT_HANDLED 0
 #define CIRRUS_HOOK_HANDLED 1
 
+#define BLTUNSAFE(s) \
+    ( \
+        ( /* check dst is within bounds */ \
+            (s)->cirrus_blt_height * (s)->cirrus_blt_dstpitch \
+                + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \
+                    (s)->vram_size \
+        ) || \
+        ( /* check src is within bounds */ \
+            (s)->cirrus_blt_height * (s)->cirrus_blt_srcpitch \
+                + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \
+                    (s)->vram_size \
+        ) \
+    )
+
 struct CirrusVGAState;
 typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
                                      uint8_t * dst, const uint8_t * src,
@@ -639,7 +653,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
 
     for (y = 0; y < lines; y++) {
 	off_cur = off_begin;
-	off_cur_end = off_cur + bytesperline;
+	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
 	off_cur &= TARGET_PAGE_MASK;
 	while (off_cur < off_cur_end) {
 	    cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
@@ -654,7 +668,11 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
 {
     uint8_t *dst;
 
-    dst = s->vram_ptr + s->cirrus_blt_dstaddr;
+    dst = s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
+
+    if (BLTUNSAFE(s))
+        return 0;
+
     (*s->cirrus_rop) (s, dst, src,
                       s->cirrus_blt_dstpitch, 0,
                       s->cirrus_blt_width, s->cirrus_blt_height);
@@ -670,8 +688,10 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
 {
     cirrus_fill_t rop_func;
 
+    if (BLTUNSAFE(s))
+        return 0;
     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
-    rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr,
+    rop_func(s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
              s->cirrus_blt_dstpitch,
              s->cirrus_blt_width, s->cirrus_blt_height);
     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
@@ -690,8 +710,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
 static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
 {
     return cirrus_bitblt_common_patterncopy(s,
-					    s->vram_ptr +
-                                            (s->cirrus_blt_srcaddr & ~7));
+					    s->vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
+                                            s->cirrus_addr_mask));
 }
 
 static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
@@ -741,8 +761,10 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
     if (notify)
 	vga_hw_update();
 
-    (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
-		      s->vram_ptr + s->cirrus_blt_srcaddr,
+    (*s->cirrus_rop) (s, s->vram_ptr +
+		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+		      s->vram_ptr +
+		      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
 		      s->cirrus_blt_width, s->cirrus_blt_height);
 
@@ -768,8 +790,14 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
 		       s->cirrus_blt_srcaddr - s->start_addr,
 		       s->cirrus_blt_width, s->cirrus_blt_height);
     } else {
-	(*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
-			  s->vram_ptr + s->cirrus_blt_srcaddr,
+
+    if (BLTUNSAFE(s))
+        return 0;
+
+	(*s->cirrus_rop) (s, s->vram_ptr +
+                (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+			  s->vram_ptr +
+                (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
 			  s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
 			  s->cirrus_blt_width, s->cirrus_blt_height);
 
@@ -801,8 +829,9 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
         } else {
             /* at least one scan line */
             do {
-                (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
-                                 s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
+                (*s->cirrus_rop)(s, s->vram_ptr +
+                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
                                          s->cirrus_blt_width, 1);
                 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
@@ -1920,7 +1949,7 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
     unsigned val = mem_value;
     uint8_t *dst;
 
-    dst = s->vram_ptr + offset;
+    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
     for (x = 0; x < 8; x++) {
 	if (val & 0x80) {
 	    *dst = s->cirrus_shadow_gr1;
@@ -1943,7 +1972,7 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
     unsigned val = mem_value;
     uint8_t *dst;
 
-    dst = s->vram_ptr + offset;
+    dst = s->vram_ptr + (offset &= s->cirrus_addr_mask);
     for (x = 0; x < 8; x++) {
 	if (val & 0x80) {
 	    *dst = s->cirrus_shadow_gr1;
diff --git a/qemu/hw/cirrus_vga_rop.h b/hw/cirrus_vga_rop.h
index 3d6a1fe..0079d12 100644
--- a/qemu/hw/cirrus_vga_rop.h
+++ b/qemu/hw/cirrus_vga_rop.h
@@ -31,6 +31,12 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
     int x,y;
     dstpitch -= bltwidth;
     srcpitch -= bltwidth;
+
+    if (dstpitch < 0 || srcpitch < 0) {
+        /* is 0 valid? srcpitch == 0 could be useful */
+        return;
+    }
+
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x++) {
             ROP_OP(*dst, *src);


Index: kvm.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kvm/F-8/kvm.spec,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- kvm.spec	23 May 2008 14:49:23 -0000	1.33
+++ kvm.spec	27 May 2008 13:26:17 -0000	1.34
@@ -1,7 +1,7 @@
 Summary: Kernel-based Virtual Machine
 Name: kvm
 Version: 60
-Release: 5%{?dist}
+Release: 6%{?dist}
 License: GPLv2+ and LGPLv2+
 Group: Development/Tools
 URL: http://%{name}.sf.net
@@ -11,6 +11,7 @@
 Patch2: %{name}-%{version}-block-rw-range-check.patch
 Patch3: %{name}-cirrus.patch
 Patch4: %{name}-60-pty-rawmode.patch
+Patch5: %{name}-cirrus-bitblt-overflow.patch
 # patches from upstream qemu
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: SDL-devel
@@ -43,6 +44,7 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
 
 %build
 # we need to install the data bits in a different path
@@ -97,6 +99,9 @@
 %{_sysconfdir}/sysconfig/modules/%{name}.modules
 
 %changelog
+* Tue May 27 2008 Glauber Costa <gcosta at redhat.com> - 60-6.fc8
+- Fix Cirrus heap overflow vulnerability (#448525)
+
 * Fri May 23 2008 Daniel P. Berrange <berrange at redhat.com> - 60-5.fc8
 - Put PTY in rawmode
 




More information about the fedora-extras-commits mailing list