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 <[email protected]>
> Tested-by: Michael Stapelberg <[email protected]>
Reviewed-by: Oliver McFadden <[email protected]>
> ---
>  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.
>   */


_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to