Mitigate UAF crashes due to wl_client_destroy reentrancy
There are situations in which a call into wl_client_destroy() can result in a reentrant call into wl_client_destroy() - which results in UAF / double free crashes.
For example, this can occur in the following scenario.
-
Server receives a message notifying it that a client has disconnected (WL_EVENT_HANGUP [1])
-
This beings client destruction with a call to wl_client_destroy()
-
wl_client_destroy() kicks off callbacks as client-associated resources are cleaned up and their destructors and destruction signals are invoked.
-
These callbacks eventually lead to an explicit call to wl_display_flush_clients() as the server attempts to flush events to other connected clients.
-
Since the client has already begun destruction, when it is reached in the iteration the flush fails wl_client_destroy() is called again [2].
This patch guards against this reentrant condition by removing the client from the display's client list when wl_client_destroy() is first called. This prevents access / iteration over the client after wl_client_destroy() is called.
In the example above, wl_display_flush_clients() will pass over the client currently undergoing destruction and the reentrant call is avoided.
Signed-off-by: Thomas Lukaszewicz thomaslukaszewicz@gmail.com