XCMS colormap tracking is not thread safe
The dEQP project noticed while running helgrind that there's thread-unsafe linked-list handling in the XCMS code in XCreateColormap
and XFreeColormap
:
Colormap XCreateColormap(
register Display *dpy,
Window w,
Visual *visual,
int alloc)
{
register xCreateColormapReq *req;
Colormap mid;
LockDisplay(dpy);
GetReq(CreateColormap, req);
req->window = w;
mid = req->mid = XAllocID(dpy);
req->alloc = alloc;
if (visual == CopyFromParent) req->visual = CopyFromParent;
else req->visual = visual->visualid;
UnlockDisplay(dpy);
SyncHandle();
#ifdef XCMS
_XcmsAddCmapRec(dpy, mid, w, visual);
#endif
return(mid);
}
Note that _XcmsAddCmapRec
is called after UnlockDisplay
. There is a similar call to _XcmsDeleteCmapRec
in XFreeColormap
. These function are not thread-safe, so calling them concurrently can corrupt the linked list.
Using the attached quick test that rapidly creates and destroys colormaps, I can reproduce both "free(): double free detected in tcache 2" and an infinite loop in _XcmsDeleteCmapRec
.
Reported by tpalli on IRC.