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]> --- 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. */ -- 1.7.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
