Fix refcounting of glyphs during ProcRenderAddGlyphs() (CVE-2024-31083)

This commit is contained in:
purplerain 2024-04-04 10:27:23 +00:00
parent f29b6fb075
commit 128113431e
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
3 changed files with 16 additions and 6 deletions

View File

@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph)
}
}
static void
void
FreeGlyph(GlyphPtr glyph, int format)
{
CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
BUG_RETURN(glyph->refcnt == 0);
if (--glyph->refcnt == 0) {
GlyphRefPtr gr;
int i;
@ -354,7 +355,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth)
glyph = (GlyphPtr) malloc(size);
if (!glyph)
return 0;
glyph->refcnt = 0;
glyph->refcnt = 1;
glyph->size = size + sizeof(xGlyphInfo);
glyph->info = *gi;
dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);

View File

@ -109,6 +109,8 @@ extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id);
extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format);
extern void FreeGlyph(GlyphPtr glyph, int format);
extern Bool
ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change);

View File

@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client)
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
glyph_new->found = TRUE;
++glyph_new->glyph->refcnt;
}
else {
GlyphPtr glyph;
@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client)
err = BadAlloc;
goto bail;
}
for (i = 0; i < nglyphs; i++)
for (i = 0; i < nglyphs; i++) {
AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
FreeGlyph(glyphs[i].glyph, glyphSet->fdepth);
}
if (glyphsBase != glyphsLocal)
free(glyphsBase);
@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client)
FreePicture((void *) pSrc, 0);
if (pSrcPix)
FreeScratchPixmapHeader(pSrcPix);
for (i = 0; i < nglyphs; i++)
if (glyphs[i].glyph && !glyphs[i].found)
free(glyphs[i].glyph);
for (i = 0; i < nglyphs; i++) {
if (glyphs[i].glyph) {
--glyphs[i].glyph->refcnt;
if (!glyphs[i].found)
free(glyphs[i].glyph);
}
}
if (glyphsBase != glyphsLocal)
free(glyphsBase);
return err;