Commit message: render: Bounds check for nglyphs in ProcRenderAddGlyphs (#28801)

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
CVE: CVE-2010-4819
CWE: CWE-20
Vulnerability description: The ProcRenderAddGlyphs function in the Render extension (render/render.c) in X.Org xserver 1.7.7 and earlier allows local users to read arbitrary memory and possibly cause a denial of service (server crash) via unspecified vectors related to an "input sanitization flaw."

Project: xserver
File: render.c

ProcRenderCreateGlyphSet (ClientPtr client)
{
    GlyphSetPtr	    glyphSet;
    PictFormatPtr   format;
    int		    rc, f;
    REQUEST(xRenderCreateGlyphSetReq);

    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);

    LEGAL_NEW_RESOURCE(stuff->gsid, client);
    rc = dixLookupResourceByType((pointer *)&format, stuff->format,
				 PictFormatType, client, DixReadAccess);
    if (rc != Success)
	return rc;

    switch (format->depth) {
    case 1:
	f = GlyphFormat1;
	break;
    case 4:
	f = GlyphFormat4;
	break;
    case 8:
	f = GlyphFormat8;
	break;
    case 16:
	f = GlyphFormat16;
	break;
    case 32:
	f = GlyphFormat32;
	break;
    default:
	return BadMatch;
    }
    if (format->type != PictTypeDirect)
	return BadMatch;
    glyphSet = AllocateGlyphSet (f, format);
    if (!glyphSet)
	return BadAlloc;
    /* security creation/labeling check */
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType,
		  glyphSet, RT_NONE, NULL, DixCreateAccess);
    if (rc != Success)
	return rc;
    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
	return BadAlloc;
    return Success;
}

Project: xserver
File: render.c

static int ProcRenderCreateRadialGradient (ClientPtr client)
{
    PicturePtr	    pPicture;
    int		    len;
    int		    error = 0;
    xFixed          *stops;
    xRenderColor   *colors;
    REQUEST(xRenderCreateRadialGradientReq);

    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);

    LEGAL_NEW_RESOURCE(stuff->pid, client);

    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
        return BadLength;

    stops = (xFixed *)(stuff + 1);
    colors = (xRenderColor *)(stops + stuff->nStops);

    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
                                            stuff->inner_radius, stuff->outer_radius,
                                            stuff->nStops, stops, colors, &error);
    if (!pPicture)
	return error;
    /* security creation/labeling check */
    error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType,
		     pPicture, RT_NONE, NULL, DixCreateAccess);
    if (error != Success)
	return error;
    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
	return BadAlloc;
    return Success;
}

Project: xserver
File: render.c

ProcRenderReferenceGlyphSet (ClientPtr client)
{
    GlyphSetPtr     glyphSet;
    int rc;
    REQUEST(xRenderReferenceGlyphSetReq);

    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);

    LEGAL_NEW_RESOURCE(stuff->gsid, client);

    rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType,
			   client, DixGetAttrAccess);
    if (rc != Success)
    {
	client->errorValue = stuff->existing;
	return rc;
    }
    glyphSet->refcnt++;
    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
	return BadAlloc;
    return Success;
}

Project: xserver
File: render.c

RenderExtensionInit (void)
{
    ExtensionEntry *extEntry;

    if (!PictureType)
	return;
    if (!PictureFinishInit ())
	return;
    if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec)))
	return;
    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
	return;

    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
			     ProcRenderDispatch, SProcRenderDispatch,
			     NULL, StandardMinorOpcode);
    if (!extEntry)
	return;
    RenderErrBase = extEntry->errorBase;
#ifdef PANORAMIX
    if (XRT_PICTURE)
	SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture);
#endif
    SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture);
    SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat);
    SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet);
}

Project: xserver
File: render.c

SProcRenderChangePicture (ClientPtr client)
{
    register int n;
    REQUEST(xRenderChangePictureReq);
    swaps(&stuff->length, n);
    swapl(&stuff->picture, n);
    swapl(&stuff->mask, n);
    SwapRestL(stuff);
    return (*ProcRenderVector[stuff->renderReqType]) (client);
}

Project: xserver
File: render.c

SProcRenderFillRectangles (ClientPtr client)
{
    register int n;
    REQUEST(xRenderFillRectanglesReq);

    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
    swaps(&stuff->length, n);
    swapl(&stuff->dst, n);
    swaps(&stuff->color.red, n);
    swaps(&stuff->color.green, n);
    swaps(&stuff->color.blue, n);
    swaps(&stuff->color.alpha, n);
    SwapRestS(stuff);
    return (*ProcRenderVector[stuff->renderReqType]) (client);
}

Project: xserver
File: render.c

SProcRenderFreeGlyphs (ClientPtr client)
{
    register int n;
    REQUEST(xRenderFreeGlyphsReq);
    swaps(&stuff->length, n);
    swapl(&stuff->glyphset, n);
    SwapRestL(stuff);
    return (*ProcRenderVector[stuff->renderReqType]) (client);
}

Project: xserver
File: render.c

SProcRenderQueryPictFormats (ClientPtr client)
{
    register int n;
    REQUEST(xRenderQueryPictFormatsReq);
    swaps(&stuff->length, n);
    return (*ProcRenderVector[stuff->renderReqType]) (client);
}

Project: xserver
File: render.c

SProcRenderTriangles (ClientPtr client)
{
    register int n;
    REQUEST(xRenderTrianglesReq);

    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
    swaps (&stuff->length, n);
    swapl (&stuff->src, n);
    swapl (&stuff->dst, n);
    swapl (&stuff->maskFormat, n);
    swaps (&stuff->xSrc, n);
    swaps (&stuff->ySrc, n);
    SwapRestL(stuff);
    return (*ProcRenderVector[stuff->renderReqType]) (client);
}