[PATCH] fb: Trim fill to drawable bounds

Oliver McFadden oliver.mcfadden at nokia.com
Fri Jul 2 06:42:15 PDT 2010


On Fri, 2010-07-02 at 15:13 +0200, ext Chris Wilson wrote:
> 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>
Reviewed-by: Oliver McFadden <oliver.mcfadden at nokia.com>
> ---
>  fb/fbfill.c    |   38 ++++++++++++++++++++++++--------------
>  include/misc.h |    1 +
>  2 files changed, 25 insertions(+), 14 deletions(-)
> 
> diff --git a/fb/fbfill.c b/fb/fbfill.c
> index 801a0d0..e76dcf1 100644
> --- a/fb/fbfill.c
> +++ b/fb/fbfill.c
> @@ -39,20 +39,31 @@ 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 = clamp(x + dstXoff,         0, pDrawable->width);
> +    x2 = clamp(x + dstXoff + width, 0, pDrawable->width);
> +
> +    y1 = clamp(y + dstYoff,          0, pDrawable->height);
> +    y2 = clamp(y + dstYoff + height, 0, 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 +87,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 +98,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 +124,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 +154,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,
> diff --git a/include/misc.h b/include/misc.h
> index 62d813e..595d4e0 100644
> --- a/include/misc.h
> +++ b/include/misc.h
> @@ -136,6 +136,7 @@ typedef struct _xReq *xReqPtr;
>  
>  #define min(a, b) (((a) < (b)) ? (a) : (b))
>  #define max(a, b) (((a) > (b)) ? (a) : (b))
> +#define clamp(v, a, b) (((v) < (a)) ? (a) : (v) > (b) ? (b) : (v))
>  /* abs() is a function, not a macro; include the file declaring
>   * it in case we haven't done that yet.
>   */




More information about the xorg-devel mailing list