Fix refcounting of glyphs during ProcRenderAddGlyphs() (CVE-2024-31083)
This commit is contained in:
parent
f29b6fb075
commit
128113431e
3 changed files with 16 additions and 6 deletions
|
@ -245,10 +245,11 @@ FreeGlyphPicture(GlyphPtr glyph)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
FreeGlyph(GlyphPtr glyph, int format)
|
FreeGlyph(GlyphPtr glyph, int format)
|
||||||
{
|
{
|
||||||
CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
|
CheckDuplicates(&globalGlyphs[format], "FreeGlyph");
|
||||||
|
BUG_RETURN(glyph->refcnt == 0);
|
||||||
if (--glyph->refcnt == 0) {
|
if (--glyph->refcnt == 0) {
|
||||||
GlyphRefPtr gr;
|
GlyphRefPtr gr;
|
||||||
int i;
|
int i;
|
||||||
|
@ -354,7 +355,7 @@ AllocateGlyph(xGlyphInfo * gi, int fdepth)
|
||||||
glyph = (GlyphPtr) malloc(size);
|
glyph = (GlyphPtr) malloc(size);
|
||||||
if (!glyph)
|
if (!glyph)
|
||||||
return 0;
|
return 0;
|
||||||
glyph->refcnt = 0;
|
glyph->refcnt = 1;
|
||||||
glyph->size = size + sizeof(xGlyphInfo);
|
glyph->size = size + sizeof(xGlyphInfo);
|
||||||
glyph->info = *gi;
|
glyph->info = *gi;
|
||||||
dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);
|
dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);
|
||||||
|
|
|
@ -109,6 +109,8 @@ extern GlyphPtr FindGlyph(GlyphSetPtr glyphSet, Glyph id);
|
||||||
|
|
||||||
extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format);
|
extern GlyphPtr AllocateGlyph(xGlyphInfo * gi, int format);
|
||||||
|
|
||||||
|
extern void FreeGlyph(GlyphPtr glyph, int format);
|
||||||
|
|
||||||
extern Bool
|
extern Bool
|
||||||
ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change);
|
ResizeGlyphSet(GlyphSetPtr glyphSet, CARD32 change);
|
||||||
|
|
||||||
|
|
|
@ -1076,6 +1076,7 @@ ProcRenderAddGlyphs(ClientPtr client)
|
||||||
|
|
||||||
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
|
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) {
|
||||||
glyph_new->found = TRUE;
|
glyph_new->found = TRUE;
|
||||||
|
++glyph_new->glyph->refcnt;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GlyphPtr glyph;
|
GlyphPtr glyph;
|
||||||
|
@ -1168,8 +1169,10 @@ ProcRenderAddGlyphs(ClientPtr client)
|
||||||
err = BadAlloc;
|
err = BadAlloc;
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
for (i = 0; i < nglyphs; i++)
|
for (i = 0; i < nglyphs; i++) {
|
||||||
AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
|
AddGlyph(glyphSet, glyphs[i].glyph, glyphs[i].id);
|
||||||
|
FreeGlyph(glyphs[i].glyph, glyphSet->fdepth);
|
||||||
|
}
|
||||||
|
|
||||||
if (glyphsBase != glyphsLocal)
|
if (glyphsBase != glyphsLocal)
|
||||||
free(glyphsBase);
|
free(glyphsBase);
|
||||||
|
@ -1179,9 +1182,13 @@ ProcRenderAddGlyphs(ClientPtr client)
|
||||||
FreePicture((void *) pSrc, 0);
|
FreePicture((void *) pSrc, 0);
|
||||||
if (pSrcPix)
|
if (pSrcPix)
|
||||||
FreeScratchPixmapHeader(pSrcPix);
|
FreeScratchPixmapHeader(pSrcPix);
|
||||||
for (i = 0; i < nglyphs; i++)
|
for (i = 0; i < nglyphs; i++) {
|
||||||
if (glyphs[i].glyph && !glyphs[i].found)
|
if (glyphs[i].glyph) {
|
||||||
free(glyphs[i].glyph);
|
--glyphs[i].glyph->refcnt;
|
||||||
|
if (!glyphs[i].found)
|
||||||
|
free(glyphs[i].glyph);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (glyphsBase != glyphsLocal)
|
if (glyphsBase != glyphsLocal)
|
||||||
free(glyphsBase);
|
free(glyphsBase);
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue