From f5889319f70408a048caf08d42a5e2502e8aa00a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 28 Feb 2024 13:37:58 +0100 Subject: [PATCH] backend/drm: fix queued cursor FB overwritten with NULL With the following sequence of events, the cursor FB fields could end up being all set to NULL while the cursor is enabled: 1. set_cursor is called, conn->cursor_pending_fb is set to a FB pointer. 2. The output is committed with a buffer. crtc->cursor->queued_fb is set to the FB pointer, conn->cursor_pending_fb is reset to NULL. A page-flip event is expected in the future. 3. The output is committed with a modeset before the page-flip event is triggered. crtc->cursor->queued_fb is reset to NULL. At this point all of crtc->cursor->current_fb, crtc->cursor->queued_fb and conn->cursor_pending_fb are NULL which is a bogus state when the cursor plane is enabled. To avoid this issue, avoid overwriting crtc->cursor->queued_fb with a NULL pointer on commit. The cursor logic still isn't great, but let's keep a rework of that for a separate patch. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3734 --- backend/drm/drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 9558b0b0..9135889e 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -471,7 +471,7 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn, if (state->primary_fb != NULL) { crtc->primary->queued_fb = drm_fb_lock(state->primary_fb); } - if (crtc->cursor != NULL) { + if (crtc->cursor != NULL && conn->cursor_pending_fb != NULL) { drm_fb_move(&crtc->cursor->queued_fb, &conn->cursor_pending_fb); }