From patchwork Sat May 16 18:38:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonas Karlman X-Patchwork-Id: 2275 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id 54B111C0085 for ; Sat, 16 May 2026 20:47:38 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=kwiboo.se; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-23415-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-23415-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id C587C30B3910 for ; Sat, 16 May 2026 18:42:15 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 271A233C53F; Sat, 16 May 2026 18:42:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kwiboo.se header.i=@kwiboo.se header.b="gz/cTEHJ" X-Original-To: linux-sunxi@lists.linux.dev Received: from smtp.forwardemail.net (smtp.forwardemail.net [149.28.215.223]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D8E432C94A for ; Sat, 16 May 2026 18:42:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=149.28.215.223 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778956925; cv=none; b=V+VYdkUv4LuKKmS6xh7/b4RetbbLU4Gis/WgyyhwGl3zp39y6DMRACbqGHpEJ5p3DPQ5ryR1kposUQJ/O8lh9kZ21VT6njxYdgn168v1batSvV590ZPLC5Mfe34mB+gD61jr1yMRKwPex5/wUWgWHmxkqTgA2WYHz3U+aOnCOlM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778956925; c=relaxed/simple; bh=VwG/RSq7gz6WMprhIVUKHmBX58f4PN4SbyLFRlUOe/g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X+u990W8/qcrJKqT/OSqRkkW6AAVDtlzIioVRNDRqtpgWny/4xVHivm3o9j89u1QSMUMcD2CSjcUk7J0gda0nwtkbBGlc1mf29ugrkK16y8NDYCixyDpgNd4CEhHKVJ8KQNb8IOX7EpQgllHaBaMDF2az7L8fkSjspClPaqznlU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=kwiboo.se; spf=pass smtp.mailfrom=fe-bounces.kwiboo.se; dkim=pass (2048-bit key) header.d=kwiboo.se header.i=@kwiboo.se header.b=gz/cTEHJ; arc=none smtp.client-ip=149.28.215.223 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=kwiboo.se Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fe-bounces.kwiboo.se DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kwiboo.se; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-ID: Date: Subject: Cc: To: From; q=dns/txt; s=fe-e1b5cab7be; t=1778956920; bh=8Xu8zmkoGpSjHmQcHYNXb6z5Nt0YqaebtxsoCwdpiVk=; b=gz/cTEHJfdkXrh6T3q04KMOeQP1Ulg7W4AaGqx3ttSZpZ5j/lzhJBEyOLbcHNULG0xQfmn9zu 4LNm7PKGiSvO492FlZoHBUnMcfJBUArD1aveuNOK7DT0fY5tyi6b/kflOG99KpJYpaLkdd19Z+J DIPj9aKD9Ar++bLgkdaGfj/MUSHuzCcYVhSeeM1TIlicX9JoUQQqNw9heGQzfc8iuVGdROrfRpf qBmil+sKFU24715GegX4YBpysh0X/1/8Midse0VBF/ZygUXXlXdsPuTfjqyGKImaRUrZnf3YzRZ QEH4SRrP0zvYqV9tpa7WX4vLRJpYaswLSQb3jOOayNsg== X-Forward-Email-ID: 6a08b9d279c7625f20eeedab X-Forward-Email-Sender: rfc822; jonas@kwiboo.se, smtp.forwardemail.net, 149.28.215.223 X-Forward-Email-Version: 2.8.12 X-Forward-Email-Website: https://forwardemail.net X-Complaints-To: abuse@forwardemail.net X-Report-Abuse: abuse@forwardemail.net X-Report-Abuse-To: abuse@forwardemail.net From: Jonas Karlman To: Andrzej Hajda , Neil Armstrong , Robert Foss , Heiko Stuebner , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Luca Ceresoli , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: Liu Ying , Sandy Huang , Andy Yan , Chen-Yu Tsai , Christian Hewitt , Diederik de Haas , Nicolas Frattaroli , Dmitry Baryshkov , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-amlogic@lists.infradead.org, linux-sunxi@lists.linux.dev, imx@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 07/22] drm: bridge: dw_hdmi: Hold bridge ref until connector cleanup Date: Sat, 16 May 2026 18:38:17 +0000 Message-ID: <20260516183838.2024991-8-jonas@kwiboo.se> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260516183838.2024991-1-jonas@kwiboo.se> References: <20260516183838.2024991-1-jonas@kwiboo.se> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= drmres connector cleanup typically run after devres has released the last dw-hdmi bridge reference. Since struct dw_hdmi, where the connector lives, is freed when the last bridge reference is released, connector cleanup can end up accessing freed memory. Call trace without a bridge reference held until connector cleanup: - dw_hdmi_bridge_detach() - dw_hdmi_bridge_destroy() <<-- struct dw_hdmi is free() - [drm:drm_managed_release] drmres release begin - [drm:drm_managed_release] REL (____ptrval____) drm_mode_config_init_release (0 bytes) - dw_hdmi_connector_destroy() - drm_connector_cleanup() <<-- drm_connector is use-after-free [...] - [drm:drm_managed_release] drmres release end Hold a bridge reference for as long as the connector exists and drop it after drm_connector_cleanup() has completed to keep struct dw_hdmi alive until connector teardown is finished and avoids the use-after-free. Call trace with a bridge reference held until connector cleanup: - dw_hdmi_bridge_detach() - [drm:drm_managed_release] drmres release begin - [drm:drm_managed_release] REL (____ptrval____) drm_mode_config_init_release (0 bytes) - dw_hdmi_connector_destroy() - drm_connector_cleanup() <<-- drm_connector is destroy() - drm_bridge_put() - dw_hdmi_bridge_destroy() <<-- struct dw_hdmi is free() [...] - [drm:drm_managed_release] drmres release end Tested-by: Diederik de Haas # Rock64, RockPro64, Quartz64-B Signed-off-by: Jonas Karlman --- v6: Collect t-b tag v5: New patch --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index a176eb55418c..cbbd15578042 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2528,10 +2528,18 @@ static void dw_hdmi_connector_force(struct drm_connector *connector) mutex_unlock(&hdmi->mutex); } +static void dw_hdmi_connector_destroy(struct drm_connector *connector) +{ + struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector); + + drm_connector_cleanup(connector); + drm_bridge_put(&hdmi->bridge); +} + static const struct drm_connector_funcs dw_hdmi_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = dw_hdmi_connector_detect, - .destroy = drm_connector_cleanup, + .destroy = dw_hdmi_connector_destroy, .force = dw_hdmi_connector_force, .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, @@ -2548,6 +2556,7 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) struct drm_connector *connector = &hdmi->connector; struct cec_connector_info conn_info; struct cec_notifier *notifier; + int ret; if (hdmi->version >= 0x200a) connector->ycbcr_420_allowed = @@ -2560,10 +2569,14 @@ static int dw_hdmi_connector_create(struct dw_hdmi *hdmi) drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs); - drm_connector_init_with_ddc(hdmi->bridge.dev, connector, - &dw_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - hdmi->ddc); + ret = drm_connector_init_with_ddc(hdmi->bridge.dev, connector, + &dw_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA, + hdmi->ddc); + if (ret) + return ret; + + drm_bridge_get(&hdmi->bridge); /* * drm_connector_attach_max_bpc_property() requires the