Hi;

This patch (rediffed againg kvm-60) from Tavis Ormandy <[EMAIL PROTECTED]> 
fixes CVE-2007-1320 [1]

Again, I'm not sure why qemu upstream not merged these but Xen already did [2].

[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1320
[2] http://xenbits.xensource.com/xen-3.1-testing.hg?rev/9e86260b95a4

diff -ur kvm-60.orig/qemu/hw/cirrus_vga.c kvm-60/qemu/hw/cirrus_vga.c
--- kvm-60.orig/qemu/hw/cirrus_vga.c    2008-01-20 14:35:04.000000000 +0200
+++ kvm-60/qemu/hw/cirrus_vga.c 2008-01-29 01:45:48.000000000 +0200
@@ -223,6 +223,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,
@@ -649,7 +663,7 @@
 
     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);
@@ -664,7 +678,11 @@
 {
     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);
@@ -680,8 +698,10 @@
 {
     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,
@@ -700,8 +720,8 @@
 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)
@@ -751,8 +771,10 @@
     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);
 
@@ -778,8 +800,14 @@
                       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);
 
@@ -811,8 +839,9 @@
         } 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;
@@ -1933,7 +1962,7 @@
     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;
@@ -1956,7 +1985,7 @@
     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;
Yalnızca kvm-60/qemu/hw'da: cirrus_vga.c.orig
diff -ur kvm-60.orig/qemu/hw/cirrus_vga_rop.h kvm-60/qemu/hw/cirrus_vga_rop.h
--- kvm-60.orig/qemu/hw/cirrus_vga_rop.h        2008-01-20 14:35:04.000000000 
+0200
+++ kvm-60/qemu/hw/cirrus_vga_rop.h     2008-01-29 01:45:48.000000000 +0200
@@ -31,6 +31,12 @@
     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);


Cheers
-- 
S.Çağlar Onur <[EMAIL PROTECTED]>
http://cekirdek.pardus.org.tr/~caglar/

Linux is like living in a teepee. No Windows, no Gates and an Apache in house!

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to