GetResReq crash after X connection is broken
In this ubuntu bug report https://bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/1941962 there is a crash while app is closing, in call from src/FreeGC.c:43
https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/master/src/FreeGC.c#L43
This is GetResReq (FreeGC, gc->gid, req);
which expands to
req = (xResourceReq *) _XGetRequest(dpy, X_FreeGC, SIZEOF(xResourceReq));
req->id = (gc->gid)
and in the crash backtrace
Thread 1 (Thread 0x7fbcc94c8cc0 (LWP 1562)):
#0 0x00007fbcc9d6a8a4 in XFreeGC (dpy=dpy@entry=0x55eb54e02470, gc=0x55eb54c41400) at ../../src/FreeGC.c:43
req = 0x0
ext = 0x0
this can only happen if _XGetRequest returns NULL.
I believe this could happen due to X connection got broken after application already started to close X display. This probably happened while systemd started transition from login display manager user account by stopping that user processes (the crashed one) while X server got concurrently killed for some reason.
I see that when X connection is broken the call from _XGetRequest
to _XFlush
will never free space in display output buffer. This may lead to requests piling up in the buffer and eventually _XGetRequest
would start returning NULL.
Now since GetResReq
is unconditionally dereferencing returned pointer, this leads to a crash with the backtrace above.
What would be appropriate strategy to handle this scenario without crashing client side? I think of an option to return static dummy request buffer instead of NULL to prevent crash, since when connection is broken it is unlikely it will get re-established anyway so effectively discarding user request is not an issue.