Commit message: New fbWalkCompositeRegion() function

This new function walks the composite region and calls a rectangle
compositing function on each compositing rectangle. Previously there
were buggy duplicates of this code in fbcompose.c and
miext/rootles/safealpha/safeAlphaPicture.c.
CVE: CVE-2010-1166
CWE: CWE-189
Vulnerability description: The fbComposite function in fbpict.c in the Render extension in the X server in X.Org X11R7.1 allows remote authenticated users to cause a denial of service (memory corruption and daemon crash) or possibly execute arbitrary code via a crafted request, related to an incorrect macro definition.

Project: xserver
File: fbcompose.c

_gradient_walker_init (GradientWalker  *walker,
		       SourcePictPtr    pGradient,
		       unsigned int     spread)
{
    walker->num_stops = pGradient->gradient.nstops;
    walker->stops     = pGradient->gradient.stops;
    walker->left_x    = 0;
    walker->right_x   = 0x10000;
    walker->stepper   = 0;
    walker->left_ag   = 0;
    walker->left_rb   = 0;
    walker->right_ag  = 0;
    walker->right_rb  = 0;
    walker->spread    = spread;

    walker->need_reset = TRUE;
}

Project: xserver
File: fbcompose.c

_gradient_walker_pixel (GradientWalker  *walker,
                        xFixed_32_32     x)
{
    int  dist, idist;
    CARD32  t1, t2, a, color;
    
    if (GRADIENT_WALKER_NEED_RESET (walker, x))
        _gradient_walker_reset (walker, x);
    
    dist  = ((int)(x - walker->left_x)*walker->stepper) >> 16;
    idist = 256 - dist;
    
    /* combined INTERPOLATE and premultiply */
    t1 = walker->left_rb*idist + walker->right_rb*dist;
    t1 = (t1 >> 8) & 0xff00ff;
    
    t2  = walker->left_ag*idist + walker->right_ag*dist;
    t2 &= 0xff00ff00;
    
    color = t2 & 0xff000000;
    a     = t2 >> 24;
    
    t1  = t1*a + 0x800080;
    t1  = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
    
    t2  = (t2 >> 8)*a + 0x800080;
    t2  = (t2 + ((t2 >> 8) & 0xff00ff));
    
    return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
}

Project: xserver
File: fbcompose.c

fbCombineConjointOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
    fbCombineConjointGeneralC (dest, src, mask, width, CombineBOver);
}

Project: xserver
File: fbcompose.c

fbCombineConjointOverU (CARD32 *dest, const CARD32 *src, int width)
{
    fbCombineConjointGeneralU (dest, src, width, CombineAOver);
}

Project: xserver
File: fbcompose.c

fbCombineDisjointOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
    fbCombineDisjointGeneralC (dest, src, mask, width, CombineAOut);
}

Project: xserver
File: fbcompose.c

fbCombineMaskC (CARD32 *src, CARD32 *mask)
{
    CARD32 a = *mask;

    CARD32	x;
    CARD16	xa;

    if (!a)
    {
	WRITE(src, 0);
	return;
    }

    x = READ(src);
    if (a == 0xffffffff)
    {
	x = x >> 24;
	x |= x << 8;
	x |= x << 16;
	WRITE(mask, x);
	return;
    }

    xa = x >> 24;
    FbByteMulC(x, a);
    WRITE(src, x);
    FbByteMul(a, xa);
    WRITE(mask, a);
}

Project: xserver
File: fbcompose.c

fbFetch_a1b5g5r5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD16 *pixel = (const CARD16 *)bits + x;
    const CARD16 *end = pixel + width;
    while (pixel < end) {
        CARD32  p = READ(pixel++);
        CARD32  r,g,b, a;

        a = (CARD32) ((CARD8) (0 - ((p & 0x8000) >> 15))) << 24;
        b = ((p & 0x7c00) | ((p & 0x7000) >> 5)) >> 7;
        g = ((p & 0x03e0) | ((p & 0x0380) >> 5)) << 6;
        r = ((p & 0x001c) | ((p & 0x001f) << 5)) << 14;
        WRITE(buffer++, (a | r | g | b));
    }
}

Project: xserver
File: fbcompose.c

fbFetch_a2b2g2r2 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD8 *pixel = (const CARD8 *)bits + x;
    const CARD8 *end = pixel + width;
    while (pixel < end) {
        CARD32  p = READ(pixel++);
        CARD32   a,r,g,b;

        a = ((p & 0xc0) * 0x55) << 18;
        b = ((p & 0x30) * 0x55) >> 6;
        g = ((p & 0x0c) * 0x55) << 6;
        r = ((p & 0x03) * 0x55) << 16;
        WRITE(buffer++, a|r|g|b);
    }
}

Project: xserver
File: fbcompose.c

fbFetch_a4r4g4b4 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD16 *pixel = (const CARD16 *)bits + x;
    const CARD16 *end = pixel + width;
    while (pixel < end) {
        CARD32  p = READ(pixel++);
        CARD32  r,g,b, a;

        a = ((p & 0xf000) | ((p & 0xf000) >> 4)) << 16;
        r = ((p & 0x0f00) | ((p & 0x0f00) >> 4)) << 12;
        g = ((p & 0x00f0) | ((p & 0x00f0) >> 4)) << 8;
        b = ((p & 0x000f) | ((p & 0x000f) << 4));
        WRITE(buffer++, (a | r | g | b));
    }
}

Project: xserver
File: fbcompose.c

fbFetch_a8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD8 *pixel = (const CARD8 *)bits + x;
    const CARD8 *end = pixel + width;
    while (pixel < end) {
        WRITE(buffer++, READ(pixel++) << 24);
    }
}

Project: xserver
File: fbcompose.c

fbFetch_b1g2r1 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    int i;
    for (i = 0; i < width; ++i) {
        CARD32  p = Fetch4(bits, i + x);
        CARD32  r,g,b;

        b = ((p & 0x8) * 0xff) >> 3;
        g = ((p & 0x6) * 0x55) << 7;
        r = ((p & 0x1) * 0xff) << 16;
        WRITE(buffer++, 0xff000000|r|g|b);
    }
}

Project: xserver
File: fbcompose.c

fbFetch_r5g6b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD16 *pixel = (const CARD16 *)bits + x;
    const CARD16 *end = pixel + width;
    while (pixel < end) {
        CARD32  p = READ(pixel++);
        CARD32 r = (((p) << 3) & 0xf8) | 
	    (((p) << 5) & 0xfc00) |
	    (((p) << 8) & 0xf80000);
        r |= (r >> 5) & 0x70007;
        r |= (r >> 6) & 0x300;
        WRITE(buffer++, 0xff000000 | r);
    }
}

Project: xserver
File: fbcompose.c

fbFetch_r8g8b8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedPtr indexed)
{
    const CARD8 *pixel = (const CARD8 *)bits + 3*x;
    const CARD8 *end = pixel + 3*width;
    while (pixel < end) {
        CARD32 b = Fetch24(pixel) | 0xff000000;
        pixel += 3;
        WRITE(buffer++, b);
    }
}

Project: xserver
File: fbcompose.c

fbStore_a1 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
{
    int i;
    for (i = 0; i < width; ++i) {
        CARD32  *pixel = ((CARD32 *) bits) + ((i+x) >> 5);
        CARD32  mask = FbStipMask((i+x) & 0x1f, 1);

        CARD32 v = READ(values + i) & 0x80000000 ? mask : 0;
        WRITE(pixel, (READ(pixel) & ~mask) | v);
    }
}

Project: xserver
File: fbcompose.c

fbStore_a4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
{
    int i;
    CARD16  *pixel = ((CARD16 *) bits) + x;
    for (i = 0; i < width; ++i) {
        Splita(READ(values + i));
        WRITE(pixel++, ((a << 8) & 0xf000) |
	      ((r << 4) & 0x0f00) |
	      ((g     ) & 0x00f0) |
	      ((b >> 4)         ));
    }
}

Project: xserver
File: fbcompose.c

fbStore_x4a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr indexed)
{
    int i;
    CARD8   *pixel = ((CARD8 *) bits) + x;
    for (i = 0; i < width; ++i) {
        WRITE(pixel++, READ(values + i) >> 28);
    }
}