]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/connector: hdmi: Do atomic check when necessary
authorLiu Ying <victor.liu@nxp.com>
Fri, 10 Jan 2025 08:48:20 +0000 (16:48 +0800)
committerMaxime Ripard <mripard@kernel.org>
Tue, 14 Jan 2025 17:43:33 +0000 (18:43 +0100)
It's ok to pass atomic check successfully if an atomic commit tries to
disable the display pipeline which the connector belongs to. That is,
when the crtc or the best_encoder pointers in struct drm_connector_state
are NULL, drm_atomic_helper_connector_hdmi_check() should return 0.
Without the check against the NULL pointers, drm_default_rgb_quant_range()
called by drm_atomic_helper_connector_hdmi_check() would dereference
the NULL pointer to_match in drm_match_cea_mode().

Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Call trace:
 drm_default_rgb_quant_range+0x0/0x4c (P)
 drm_bridge_connector_atomic_check+0x20/0x2c
 drm_atomic_helper_check_modeset+0x488/0xc78
 drm_atomic_helper_check+0x20/0xa4
 drm_atomic_check_only+0x4b8/0x984
 drm_atomic_commit+0x48/0xc4
 drm_framebuffer_remove+0x44c/0x530
 drm_mode_rmfb_work_fn+0x7c/0xa0
 process_one_work+0x150/0x294
 worker_thread+0x2dc/0x3dc
 kthread+0x130/0x204
 ret_from_fork+0x10/0x20

Fixes: 8ec116ff21a9 ("drm/display: bridge_connector: provide atomic_check for HDMI bridges")
Fixes: 84e541b1e58e ("drm/sun4i: use drm_atomic_helper_connector_hdmi_check()")
Fixes: 65548c8ff0ab ("drm/rockchip: inno_hdmi: Switch to HDMI connector")
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20250110084821.3239518-2-victor.liu@nxp.com
Signed-off-by: Maxime Ripard <mripard@kernel.org>
drivers/gpu/drm/display/drm_hdmi_state_helper.c

index cfc2aaee1da08a103cbf933c891d5cc31b0886a8..daaf68b80e5fe189d52bec07ca3f0c774dcb956e 100644 (file)
@@ -503,6 +503,9 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,
                connector_state_get_mode(new_conn_state);
        int ret;
 
+       if (!new_conn_state->crtc || !new_conn_state->best_encoder)
+               return 0;
+
        new_conn_state->hdmi.is_limited_range = hdmi_is_limited_range(connector, new_conn_state);
 
        ret = hdmi_compute_config(connector, new_conn_state, mode);