References: bsc#1035483 CVE-2017-7980 

Subject: cirrus: stop passing around dst pointers in the blitter
From: Gerd Hoffmann kraxel@redhat.com Wed Mar 15 11:47:52 2017 +0100
Date: Thu Mar 16 08:58:15 2017 +0100:
Git: 026aeffcb4752054830ba203020ed6eb05bcaba8

Instead pass around the address (aka offset into vga memory).  Calculate
the pointer in the rop_* functions, after applying the mask to the
address, to make sure the address stays within the valid range.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1489574872-8679-1-git-send-email-kraxel@redhat.com

Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga.c
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/hw/display/cirrus_vga.c
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga.c
@@ -174,11 +174,12 @@
 
 struct CirrusVGAState;
 typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
-                                     uint8_t * dst, const uint8_t * src,
+                                     uint32_t dstaddr, const uint8_t *src,
 				     int dstpitch, int srcpitch,
 				     int bltwidth, int bltheight);
 typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
-                              uint8_t *dst, int dst_pitch, int width, int height);
+                              uint32_t dstaddr, int dst_pitch,
+                              int width, int height);
 
 typedef struct CirrusVGAState {
     VGACommonState vga;
@@ -308,14 +309,14 @@ static bool blit_is_unsafe(struct Cirrus
 }
 
 static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
-                                  uint8_t *dst,const uint8_t *src,
+                                  uint32_t dstaddr, const uint8_t *src,
                                   int dstpitch,int srcpitch,
                                   int bltwidth,int bltheight)
 {
 }
 
 static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
-                                   uint8_t *dst,
+                                   uint32_t dstaddr,
                                    int dstpitch, int bltwidth,int bltheight)
 {
 }
@@ -660,14 +661,10 @@ static void cirrus_invalidate_region(Cir
 static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
 					    const uint8_t * src)
 {
-    uint8_t *dst;
-
-    dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
-
     if (blit_is_unsafe(s))
         return 0;
 
-    (*s->cirrus_rop) (s, dst, src,
+    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, src,
                       s->cirrus_blt_dstpitch, 0,
                       s->cirrus_blt_width, s->cirrus_blt_height);
     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
@@ -686,7 +683,7 @@ static int cirrus_bitblt_solidfill(Cirru
         return 0;
     }
     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
-    rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+    rop_func(s, (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,
@@ -755,8 +752,7 @@ static int cirrus_do_copy(CirrusVGAState
         }
     }
 
-    (*s->cirrus_rop) (s, s->vga.vram_ptr +
-		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+    (*s->cirrus_rop) (s, (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
 		      s->vga.vram_ptr +
 		      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
@@ -808,8 +804,7 @@ static void cirrus_bitblt_cputovideo_nex
         } else {
             /* at least one scan line */
             do {
-                (*s->cirrus_rop)(s, s->vga.vram_ptr +
-                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+                (*s->cirrus_rop)(s, (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);
Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop.h
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop.h
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop.h
@@ -22,31 +22,65 @@
  * THE SOFTWARE.
  */
 
-static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
+static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s,
+                                          uint32_t dstaddr, uint8_t src)
 {
+    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
     *dst = ROP_FN(*dst, src);
 }
 
-static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
+static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s,
+                                             uint32_t dstaddr, uint8_t src,
+                                             uint8_t transp)
 {
+    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
+    uint8_t pixel = ROP_FN(*dst, src);
+    if (pixel != transp) {
+        *dst = pixel;
+    }
+}
+
+static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s,
+                                           uint32_t dstaddr, uint16_t src)
+{
+    uint16_t *dst = (uint16_t *)
+        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
     *dst = ROP_FN(*dst, src);
 }
 
-static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
+static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s,
+                                              uint32_t dstaddr, uint16_t src,
+                                              uint16_t transp)
+{
+    uint16_t *dst = (uint16_t *)
+        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
+    uint16_t pixel = ROP_FN(*dst, src);
+    if (pixel != transp) {
+        *dst = pixel;
+    }
+}
+
+static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s,
+                                           uint32_t dstaddr, uint32_t src)
 {
+    uint32_t *dst = (uint32_t *)
+        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]);
     *dst = ROP_FN(*dst, src);
 }
 
-#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
-#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
-#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
+#define ROP_OP(st, d, s)           glue(rop_8_, ROP_NAME)(st, d, s)
+#define ROP_OP_TR(st, d, s, t)     glue(rop_tr_8_, ROP_NAME)(st, d, s, t)
+#define ROP_OP_16(st, d, s)        glue(rop_16_, ROP_NAME)(st, d, s)
+#define ROP_OP_TR_16(st, d, s, t)  glue(rop_tr_16_, ROP_NAME)(st, d, s, t)
+#define ROP_OP_32(st, d, s)        glue(rop_32_, ROP_NAME)(st, d, s)
 #undef ROP_FN
 
 static void
 glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
-                             uint8_t *dst,const uint8_t *src,
-                             int dstpitch,int srcpitch,
-                             int bltwidth,int bltheight)
+                                       uint32_t dstaddr,
+                                       const uint8_t *src,
+                                       int dstpitch, int srcpitch,
+                                       int bltwidth, int bltheight)
 {
     int x,y;
     dstpitch -= bltwidth;
@@ -59,43 +93,47 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(C
 
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x++) {
-            ROP_OP(dst, *src);
-            dst++;
+            ROP_OP(s, dstaddr, *src);
+            dstaddr++;
             src++;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
 
 static void
 glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
-                                        uint8_t *dst,const uint8_t *src,
-                                        int dstpitch,int srcpitch,
-                                        int bltwidth,int bltheight)
+                                        uint32_t dstaddr,
+                                        const uint8_t *src,
+                                        int dstpitch, int srcpitch,
+                                        int bltwidth, int bltheight)
 {
     int x,y;
     dstpitch += bltwidth;
     srcpitch += bltwidth;
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x++) {
-            ROP_OP(dst, *src);
-            dst--;
+            ROP_OP(s, dstaddr, *src);
+            dstaddr--;
             src--;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
 
 static void
 glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
-						       uint8_t *dst,const uint8_t *src,
-						       int dstpitch,int srcpitch,
-						       int bltwidth,int bltheight)
+                                                       uint32_t dstaddr,
+                                                       const uint8_t *src,
+                                                       int dstpitch,
+                                                       int srcpitch,
+                                                       int bltwidth,
+                                                       int bltheight)
 {
     int x,y;
-    uint8_t p;
+    uint8_t transp = s->vga.gr[0x34];
     dstpitch -= bltwidth;
     srcpitch -= bltwidth;
 
@@ -105,48 +143,50 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
 
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x++) {
-	    p = *dst;
-            ROP_OP(&p, *src);
-	    if (p != s->vga.gr[0x34]) *dst = p;
-            dst++;
+            ROP_OP_TR(s, dstaddr, *src, transp);
+            dstaddr++;
             src++;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
 
 static void
 glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
-							uint8_t *dst,const uint8_t *src,
-							int dstpitch,int srcpitch,
-							int bltwidth,int bltheight)
+                                                        uint32_t dstaddr,
+                                                        const uint8_t *src,
+                                                        int dstpitch,
+                                                        int srcpitch,
+                                                        int bltwidth,
+                                                        int bltheight)
 {
     int x,y;
-    uint8_t p;
+    uint8_t transp = s->vga.gr[0x34];
     dstpitch += bltwidth;
     srcpitch += bltwidth;
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x++) {
-	    p = *dst;
-            ROP_OP(&p, *src);
-	    if (p != s->vga.gr[0x34]) *dst = p;
-            dst--;
+            ROP_OP_TR(s, dstaddr, *src, transp);
+            dstaddr--;
             src--;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
 
 static void
 glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
-							uint8_t *dst,const uint8_t *src,
-							int dstpitch,int srcpitch,
-							int bltwidth,int bltheight)
+                                                        uint32_t dstaddr,
+                                                        const uint8_t *src,
+                                                        int dstpitch,
+                                                        int srcpitch,
+                                                        int bltwidth,
+                                                        int bltheight)
 {
     int x,y;
-    uint8_t p1, p2;
+    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
     dstpitch -= bltwidth;
     srcpitch -= bltwidth;
 
@@ -156,46 +196,35 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
 
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x+=2) {
-	    p1 = *dst;
-	    p2 = *(dst+1);
-            ROP_OP(&p1, *src);
-            ROP_OP(&p2, *(src + 1));
-	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
-		*dst = p1;
-		*(dst+1) = p2;
-	    }
-            dst+=2;
-            src+=2;
+            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
+            dstaddr += 2;
+            src += 2;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
 
 static void
 glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
-							 uint8_t *dst,const uint8_t *src,
-							 int dstpitch,int srcpitch,
-							 int bltwidth,int bltheight)
+                                                         uint32_t dstaddr,
+                                                         const uint8_t *src,
+                                                         int dstpitch,
+                                                         int srcpitch,
+                                                         int bltwidth,
+                                                         int bltheight)
 {
     int x,y;
-    uint8_t p1, p2;
+    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
     dstpitch += bltwidth;
     srcpitch += bltwidth;
     for (y = 0; y < bltheight; y++) {
         for (x = 0; x < bltwidth; x+=2) {
-	    p1 = *(dst-1);
-	    p2 = *dst;
-            ROP_OP(&p1, *(src - 1));
-            ROP_OP(&p2, *src);
-	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
-		*(dst-1) = p1;
-		*dst = p2;
-	    }
-            dst-=2;
-            src-=2;
+            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
+            dstaddr -= 2;
+            src -= 2;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
         src += srcpitch;
     }
 }
Index: xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop2.h
===================================================================
--- xen-4.5.5-testing.orig/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop2.h
+++ xen-4.5.5-testing/tools/qemu-xen-dir-remote/hw/display/cirrus_vga_rop2.h
@@ -23,27 +23,29 @@
  */
 
 #if DEPTH == 8
-#define PUTPIXEL()    ROP_OP(&d[0], col)
+#define PUTPIXEL(s, a, c)    ROP_OP(s, a, c)
 #elif DEPTH == 16
-#define PUTPIXEL()    ROP_OP_16((uint16_t *)&d[0], col)
+#define PUTPIXEL(s, a, c)    ROP_OP_16(s, a, c)
 #elif DEPTH == 24
-#define PUTPIXEL()    ROP_OP(&d[0], col);        \
-                      ROP_OP(&d[1], (col >> 8)); \
-                      ROP_OP(&d[2], (col >> 16))
+#define PUTPIXEL(s, a, c)    do {          \
+        ROP_OP(s, a,     c);               \
+        ROP_OP(s, a + 1, (col >> 8));      \
+        ROP_OP(s, a + 2, (col >> 16));     \
+    } while (0)
 #elif DEPTH == 32
-#define PUTPIXEL()    ROP_OP_32(((uint32_t *)&d[0]), col)
+#define PUTPIXEL(s, a, c)    ROP_OP_32(s, a, c)
 #else
 #error unsupported DEPTH
 #endif
 
 static void
 glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
-     (CirrusVGAState * s, uint8_t * dst,
-      const uint8_t * src,
+     (CirrusVGAState *s, uint32_t dstaddr,
+      const uint8_t *src,
       int dstpitch, int srcpitch,
       int bltwidth, int bltheight)
 {
-    uint8_t *d;
+    uint32_t addr;
     int x, y, pattern_y, pattern_pitch, pattern_x;
     unsigned int col;
     const uint8_t *src1;
@@ -63,7 +65,7 @@ glue(glue(glue(cirrus_patternfill_, ROP_
     pattern_y = s->cirrus_blt_srcaddr & 7;
     for(y = 0; y < bltheight; y++) {
         pattern_x = skipleft;
-        d = dst + skipleft;
+        addr = dstaddr + skipleft;
         src1 = src + pattern_y * pattern_pitch;
         for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
 #if DEPTH == 8
@@ -82,23 +84,23 @@ glue(glue(glue(cirrus_patternfill_, ROP_
             col = ((uint32_t *)(src1 + pattern_x))[0];
             pattern_x = (pattern_x + 4) & 31;
 #endif
-            PUTPIXEL();
-            d += (DEPTH / 8);
+            PUTPIXEL(s, addr, col);
+            addr += (DEPTH / 8);
         }
         pattern_y = (pattern_y + 1) & 7;
-        dst += dstpitch;
+        dstaddr += dstpitch;
     }
 }
 
 /* NOTE: srcpitch is ignored */
 static void
 glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
-     (CirrusVGAState * s, uint8_t * dst,
-      const uint8_t * src,
+     (CirrusVGAState *s, uint32_t dstaddr,
+      const uint8_t *src,
       int dstpitch, int srcpitch,
       int bltwidth, int bltheight)
 {
-    uint8_t *d;
+    uint32_t addr;
     int x, y;
     unsigned bits, bits_xor;
     unsigned int col;
@@ -123,7 +125,7 @@ glue(glue(glue(cirrus_colorexpand_transp
     for(y = 0; y < bltheight; y++) {
         bitmask = 0x80 >> srcskipleft;
         bits = *src++ ^ bits_xor;
-        d = dst + dstskipleft;
+        addr = dstaddr + dstskipleft;
         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
             if ((bitmask & 0xff) == 0) {
                 bitmask = 0x80;
@@ -131,24 +133,24 @@ glue(glue(glue(cirrus_colorexpand_transp
             }
             index = (bits & bitmask);
             if (index) {
-                PUTPIXEL();
+                PUTPIXEL(s, addr, col);
             }
-            d += (DEPTH / 8);
+            addr += (DEPTH / 8);
             bitmask >>= 1;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
     }
 }
 
 static void
 glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
-     (CirrusVGAState * s, uint8_t * dst,
-      const uint8_t * src,
+     (CirrusVGAState *s, uint32_t dstaddr,
+      const uint8_t *src,
       int dstpitch, int srcpitch,
       int bltwidth, int bltheight)
 {
     uint32_t colors[2];
-    uint8_t *d;
+    uint32_t addr;
     int x, y;
     unsigned bits;
     unsigned int col;
@@ -161,29 +163,29 @@ glue(glue(glue(cirrus_colorexpand_, ROP_
     for(y = 0; y < bltheight; y++) {
         bitmask = 0x80 >> srcskipleft;
         bits = *src++;
-        d = dst + dstskipleft;
+        addr = dstaddr + dstskipleft;
         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
             if ((bitmask & 0xff) == 0) {
                 bitmask = 0x80;
                 bits = *src++;
             }
             col = colors[!!(bits & bitmask)];
-            PUTPIXEL();
-            d += (DEPTH / 8);
+            PUTPIXEL(s, addr, col);
+            addr += (DEPTH / 8);
             bitmask >>= 1;
         }
-        dst += dstpitch;
+        dstaddr += dstpitch;
     }
 }
 
 static void
 glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
-     (CirrusVGAState * s, uint8_t * dst,
-      const uint8_t * src,
+     (CirrusVGAState *s, uint32_t dstaddr,
+      const uint8_t *src,
       int dstpitch, int srcpitch,
       int bltwidth, int bltheight)
 {
-    uint8_t *d;
+    uint32_t addr;
     int x, y, bitpos, pattern_y;
     unsigned int bits, bits_xor;
     unsigned int col;
@@ -207,28 +209,28 @@ glue(glue(glue(cirrus_colorexpand_patter
     for(y = 0; y < bltheight; y++) {
         bits = src[pattern_y] ^ bits_xor;
         bitpos = 7 - srcskipleft;
-        d = dst + dstskipleft;
+        addr = dstaddr + dstskipleft;
         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
             if ((bits >> bitpos) & 1) {
-                PUTPIXEL();
+                PUTPIXEL(s, addr, col);
             }
-            d += (DEPTH / 8);
+            addr += (DEPTH / 8);
             bitpos = (bitpos - 1) & 7;
         }
         pattern_y = (pattern_y + 1) & 7;
-        dst += dstpitch;
+        dstaddr += dstpitch;
     }
 }
 
 static void
 glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
-     (CirrusVGAState * s, uint8_t * dst,
-      const uint8_t * src,
+     (CirrusVGAState *s, uint32_t dstaddr,
+      const uint8_t *src,
       int dstpitch, int srcpitch,
       int bltwidth, int bltheight)
 {
     uint32_t colors[2];
-    uint8_t *d;
+    uint32_t addr;
     int x, y, bitpos, pattern_y;
     unsigned int bits;
     unsigned int col;
@@ -242,38 +244,37 @@ glue(glue(glue(cirrus_colorexpand_patter
     for(y = 0; y < bltheight; y++) {
         bits = src[pattern_y];
         bitpos = 7 - srcskipleft;
-        d = dst + dstskipleft;
+        addr = dstaddr + dstskipleft;
         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
             col = colors[(bits >> bitpos) & 1];
-            PUTPIXEL();
-            d += (DEPTH / 8);
+            PUTPIXEL(s, addr, col);
+            addr += (DEPTH / 8);
             bitpos = (bitpos - 1) & 7;
         }
         pattern_y = (pattern_y + 1) & 7;
-        dst += dstpitch;
+        dstaddr += dstpitch;
     }
 }
 
 static void
 glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
      (CirrusVGAState *s,
-      uint8_t *dst, int dst_pitch,
+      uint32_t dstaddr, int dst_pitch,
       int width, int height)
 {
-    uint8_t *d, *d1;
+    uint32_t addr;
     uint32_t col;
     int x, y;
 
     col = s->cirrus_blt_fgcol;
 
-    d1 = dst;
     for(y = 0; y < height; y++) {
-        d = d1;
+        addr = dstaddr;
         for(x = 0; x < width; x += (DEPTH / 8)) {
-            PUTPIXEL();
-            d += (DEPTH / 8);
+            PUTPIXEL(s, addr, col);
+            addr += (DEPTH / 8);
         }
-        d1 += dst_pitch;
+        dstaddr += dst_pitch;
     }
 }
 
