Skip to content

Mitigate UAF crashes due to wl_client_destroy reentrancy

Thomas Lukaszewicz requested to merge tluk/wayland:client-destruction-guard into main

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.

  1. Server receives a message notifying it that a client has disconnected (WL_EVENT_HANGUP [1])

  2. This beings client destruction with a call to wl_client_destroy()

  3. wl_client_destroy() kicks off callbacks as client-associated resources are cleaned up and their destructors and destruction signals are invoked.

  4. These callbacks eventually lead to an explicit call to wl_display_flush_clients() as the server attempts to flush events to other connected clients.

  5. 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.

[1] https://gitlab.freedesktop.org/wayland/wayland/-/blob/8f499bf4045f88f3a4b4b0a445befca467bebe20/src/wayland-server.c#L342

[2] https://gitlab.freedesktop.org/wayland/wayland/-/blob/8f499bf4045f88f3a4b4b0a445befca467bebe20/src/wayland-server.c#L1512

Signed-off-by: Thomas Lukaszewicz thomaslukaszewicz@gmail.com

Edited by Thomas Lukaszewicz

Merge request reports