[PATCH] fb: Trim fill to drawable bounds

Chris Wilson chris at chris-wilson.co.uk
Fri Jul 2 01:43:18 PDT 2010


Fixes:

  Bug 27313 - random X11 crash (SIGSEGV) when rendering firefox in pixman/intel
  https://bugs.freedesktop.org/show_bug.cgi?id=27313

As pixman does not guard against a fill request outside of the buffer,
we must be be careful and trim oversized fills.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Tested-by: Michael Stapelberg <michael+freedesktop at stapelberg.de>
---
 fb/fbfill.c |   44 ++++++++++++++++++++++++++++++--------------
 1 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/fb/fbfill.c b/fb/fbfill.c
index 801a0d0..fddf042 100644
--- a/fb/fbfill.c
+++ b/fb/fbfill.c
@@ -39,20 +39,37 @@ fbFill (DrawablePtr pDrawable,
     int		    dstBpp;
     int		    dstXoff, dstYoff;
     FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
-    
+    int x1, x2, y1, y2;
+
     fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 
+    /* trim fill to drawable bounds */
+    x1 = x + dstXoff;
+    y1 = y + dstYoff;
+    x2 = x1 + width;
+    y2 = y1 + height;
+    if (x1 < 0)
+	x1 = 0;
+    if (x2 > pDrawable->width)
+	x2 = pDrawable->width;
+    if (y1 < 0)
+	y1 = 0;
+    if (y2 > pDrawable->height)
+	y2 = pDrawable->height;
+    width  = x2 - x1;
+    height = y2 - y1;
+
     switch (pGC->fillStyle) {
     case FillSolid:
 #ifndef FB_ACCESS_WRAPPER
 	if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
-					x + dstXoff, y + dstYoff,
+					x1, y1,
 					width, height,
 					pPriv->xor))
 #endif	    
-	    fbSolid (dst + (y + dstYoff) * dstStride, 
-		     dstStride, 
-		     (x + dstXoff) * dstBpp,
+	    fbSolid (dst + y1 * dstStride,
+		     dstStride,
+		     x1 * dstBpp,
 		     dstBpp,
 		     width * dstBpp, height,
 		     pPriv->and, pPriv->xor);
@@ -76,9 +93,9 @@ fbFill (DrawablePtr pDrawable,
 	    else
 		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
 	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
-	    fbTile (dst + (y + dstYoff) * dstStride,
+	    fbTile (dst + y1 * dstStride,
 		    dstStride,
-		    x + dstXoff,
+		    x1,
 		    width, height,
 		    stip,
 		    stipStride,
@@ -87,7 +104,6 @@ fbFill (DrawablePtr pDrawable,
 		    alu,
 		    pPriv->pm,
 		    dstBpp,
-		    
 		    (pGC->patOrg.x + pDrawable->x + dstXoff),
 		    pGC->patOrg.y + pDrawable->y - y);
 	    fbFinishAccess (&pStip->drawable);
@@ -114,9 +130,9 @@ fbFill (DrawablePtr pDrawable,
 	    }
 
 	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
-	    fbStipple (dst + (y + dstYoff) * dstStride, 
-		       dstStride, 
-		       (x + dstXoff) * dstBpp,
+	    fbStipple (dst + y1 * dstStride,
+		       dstStride,
+		       x1 * dstBpp,
 		       dstBpp,
 		       width * dstBpp, height,
 		       stip,
@@ -144,9 +160,9 @@ fbFill (DrawablePtr pDrawable,
 	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
 	tileWidth = pTile->drawable.width;
 	tileHeight = pTile->drawable.height;
-	fbTile (dst + (y + dstYoff) * dstStride, 
-		dstStride, 
-		(x + dstXoff) * dstBpp, 
+	fbTile (dst + y1 * dstStride,
+		dstStride,
+		x1 * dstBpp,
 		width * dstBpp, height,
 		tile,
 		tileStride,
-- 
1.7.1



More information about the xorg-devel mailing list