From 1c4a625fe3e6bc3317d3e1816eee4a701a36c588 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 10 Nov 2022 12:48:29 +0100 Subject: [PATCH] backend/drm: ensure disconnected outputs are disabled after VT switch The following situation can be dangerous: - Output DP-1 is plugged in, compositor enables it. - User VT switches away. - User unplugs DP-1. - User VT switches back. - scan_drm_connectors() figures out the output is now disconnected, uninitializes the struct wlr_output. - The loop restoring previous output state in handle_session_active() accesses the struct wlr_output to figure out what to restore. By chance, we zero out the struct wlr_output after uninitializing it, so enabled and current_mode will always be zero. But let's make sure we handle this case explicitly, to remind future readers that it exists and make the code less fragile. --- backend/drm/backend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/drm/backend.c b/backend/drm/backend.c index a7400eab..fc383832 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -107,7 +107,8 @@ static void handle_session_active(struct wl_listener *listener, void *data) { wl_list_for_each(conn, &drm->outputs, link) { struct wlr_output_mode *mode = NULL; uint32_t committed = WLR_OUTPUT_STATE_ENABLED; - if (conn->output.enabled && conn->output.current_mode != NULL) { + if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled + && conn->output.current_mode != NULL) { committed |= WLR_OUTPUT_STATE_MODE; mode = conn->output.current_mode; }