From 55a67aa89342545b89f469dea6f29bfb6fac6f3d Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Thu, 17 Sep 2026 11:44:33 +0530 Subject: [PATCH] drm/amd/display: Fix NULL sink dereference in USB4 bandwidth functions allocate_usb4_bandwidth_for_stream() and allocate_usb4_bandwidth() both use ASSERT(stream->sink) before dereferencing stream->sink->link. ASSERT is compiled out in production builds, so a NULL stream->sink causes a NULL pointer dereference. link_set_dpms_off() already guards two earlier accesses to stream->sink with explicit NULL checks, confirming that stream->sink can legitimately be NULL. The subsequent call to deallocate_usb4_bandwidth() had no equivalent guard. Replace the ASSERT() calls with proper NULL checks that return false early, and add a matching stream->sink guard at the call site in link_set_dpms_off() consistent with the surrounding pattern. v2: Keep the existing ASSERT() calls for diagnostics (to report unexpected NULL sink), and add explicit NULL checks that return false before dereferencing stream->sink. Also add a matching stream->sink guard at the deallocation call site in link_set_dpms_off(). (Alex) Fixes: 8fa813b7fd1e ("drm/amd/display: Remove sink usage from DPMS") Reported-by: Dan Carpenter Cc: Nicholas Kazlauskas Cc: Dominik Kaszewski Cc: George Zhang Cc: Aurabindo Pillai Cc: Roman Li Cc: Ivan Lipski Cc: Dan Wheeler Cc: Alex Hung Cc: Tom Chung Signed-off-by: Srinivasan Shanmugam Tested-by: Dan Wheeler Reviewed-by: Roman Li Signed-off-by: Alex Deucher (cherry picked from commit 98029a0ce61feb52c563f65349dd9b25f672e355) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/dc/link/link_dpms.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 48b086d15ab0..25ec3d38a14e 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2306,9 +2306,14 @@ static bool allocate_usb4_bandwidth_for_stream(struct dc_stream_state *stream, i { ASSERT(stream->sink); - struct dc_link *link = stream->sink->link; + struct dc_link *link; int req_bw = stream_bw; + if (!stream->sink) + return false; + + link = stream->sink->link; + DC_LOGGER_INIT(link->ctx->logger); if (!link->dpia_bw_alloc_config.bw_alloc_enabled) @@ -2355,9 +2360,13 @@ static bool allocate_usb4_bandwidth(struct dc_stream_state *stream) ASSERT(stream->sink); bool ret; + int bw; - int bw = dc_bandwidth_in_kbps_from_timing(&stream->timing, - dc_link_get_highest_encoding_format(stream->sink->link)); + if (!stream->sink) + return false; + + bw = dc_bandwidth_in_kbps_from_timing(&stream->timing, + dc_link_get_highest_encoding_format(stream->sink->link)); ret = allocate_usb4_bandwidth_for_stream(stream, bw); @@ -2419,7 +2428,8 @@ enum dc_status link_set_dpms_off(struct pipe_ctx *pipe_ctx) update_psp_stream_config(pipe_ctx, true); dc->hwss.blank_stream(pipe_ctx); - if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation) + if (pipe_ctx->link_config.dp_tunnel_settings.should_use_dp_bw_allocation && + stream->sink) deallocate_usb4_bandwidth(stream); if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)