| Message ID | 20260901-dw-hdmi-qp-scramb-v11-31-bc12954a0688@collabora.com (mailing list archive) |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-sunxi+bounces-25421-sunxi=pue.re@lists.linux.dev> X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74]) by mxe881.netcup.net (Postfix) with ESMTPS id C1AFF1C002D for <noreply@patchwork.local>; Tue, 1 Sep 2026 20:55:37 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=collabora.com; spf=pass (sender IP is 172.232.135.74) smtp.mailfrom=linux-sunxi+bounces-25421-noreply=patchwork.local@lists.linux.dev smtp.helo=sto.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.232.135.74 as permitted sender) client-ip=172.232.135.74; envelope-from=linux-sunxi+bounces-25421-noreply=patchwork.local@lists.linux.dev; helo=sto.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sto.lore.kernel.org (Postfix) with ESMTP id 885846011D9 for <noreply@patchwork.local>; Tue, 1 Sep 2026 18:54:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CE9344A482D; Tue, 1 Sep 2026 18:51:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="D6cZJmAk" X-Original-To: linux-sunxi@lists.linux.dev Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03F534A090B for <linux-sunxi@lists.linux.dev>; Tue, 1 Sep 2026 18:51:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788288668; cv=none; b=teccgtKYICjh4XbhiQtAsQ90cBoBFOSmDSIkghk45epGU4JqhZamy3ig+kozk9rRJxegLcuyNk2UQ1WIklAIjod878R4InfZqfkgbPUdojZ1Q1FhQbBvNxXpAeM23ZozGS0YfBj/K7F6572s761Nq6E0Tg7TpgnAU8knKQPW/Nk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788288668; c=relaxed/simple; bh=8nvSV+nWPFUZXqT08BM59NFazu9V0O6/Yz51yOFt+3A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tNBzeO57CijbDbTp4EKIcgOyjTq2O8KS/OWtA61Qvu3ljtGVSCR/MKm1StUT3F75iTK5wS3tECsFynwJycyJC6fmfcnQtTPt9UtDFw2jT2uJCqKQ8Rrua0kHnpazhQl5l2QK/Lvb+XeOD1ni3RT6wHGV9fTZ9a+g0ofv6yHNi5o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=D6cZJmAk; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1788288664; bh=8nvSV+nWPFUZXqT08BM59NFazu9V0O6/Yz51yOFt+3A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D6cZJmAkzhA5GZ0QcfJZCbgDpVhPyOaD9Ka7KjdcYm6bTIFCX5tfAIA45R33ZSggU uPCZOOqoQZqam6ylnw4ZoMhOFdx6IehsF/o1zbHYJ7L2Z8pX7W7Xr7NNRAZSVJwL9/ 3Rh4jjA68Lt1UYeMs1CmqbZrvkZuHw/ztr5XEMPCy/k0dLMPeAzASjVf9qACG/SOFc 7bQgZDqdVarZI1Bob5FR65Ll7aAPQOKdnvBPL8eEjyg54zvbkLQtc1y120HinKXFtA dXd5sowYlPcJ86OcYCj54fIOGNRg0fGYqTm+4FgPa8PgYqjMjsUvhqXMK3y8fnluoa L1g5z61POSHIQ== Received: from localhost (unknown [100.64.0.241]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange secp256r1 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: cristicc) by bali.collaboradmins.com (Postfix) with ESMTPSA id EC04D17E3ACB; Tue, 01 Sep 2026 20:51:03 +0200 (CEST) From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> Date: Tue, 01 Sep 2026 21:50:55 +0300 Subject: [PATCH v11 31/74] drm/rockchip: dw_hdmi_qp: Fix invalid drvdata access in PM ops Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: <linux-sunxi.lists.linux.dev> List-Subscribe: <mailto:linux-sunxi+subscribe@lists.linux.dev> List-Unsubscribe: <mailto:linux-sunxi+unsubscribe@lists.linux.dev> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260901-dw-hdmi-qp-scramb-v11-31-bc12954a0688@collabora.com> References: <20260901-dw-hdmi-qp-scramb-v11-0-bc12954a0688@collabora.com> In-Reply-To: <20260901-dw-hdmi-qp-scramb-v11-0-bc12954a0688@collabora.com> To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>, David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>, Dave Stevenson <dave.stevenson@raspberrypi.com>, Dmitry Baryshkov <lumag@kernel.org>, Andrzej Hajda <andrzej.hajda@intel.com>, Neil Armstrong <neil.armstrong@linaro.org>, Robert Foss <rfoss@kernel.org>, Laurent Pinchart <Laurent.pinchart@ideasonboard.com>, Jonas Karlman <jonas@kwiboo.se>, Jernej Skrabec <jernej.skrabec@gmail.com>, Luca Ceresoli <luca.ceresoli@bootlin.com>, Chen-Yu Tsai <wens@kernel.org>, Samuel Holland <samuel@sholland.org>, =?utf-8?q?Ma=C3=ADra_Canal?= <mcanal@igalia.com>, Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>, Raphael Gallais-Pou <rgallaispou@gmail.com>, Sandy Huang <hjc@rock-chips.com>, =?utf-8?q?Heiko_St=C3=BCbner?= <heiko@sntech.de>, Andy Yan <andy.yan@rock-chips.com>, Algea Cao <algea.cao@rock-chips.com>, Daniel Stone <daniels@collabora.com>, Liu Ying <victor.liu@nxp.com>, Phong LE <ple@baylibre.com>, Helge Deller <deller@gmx.de> Cc: kernel@collabora.com, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-rockchip@lists.infradead.org, linux-fbdev@vger.kernel.org, Sashiko <sashiko-bot@kernel.org> X-Mailer: b4 0.15.2 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [3.34 / 15.00]; RBL_SENDERSCORE(2.00)[172.232.135.74:from]; SUSPICIOUS_RECIPS(1.50)[]; MAILLIST(-0.15)[generic]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_COUNT_FIVE(0.00)[5]; FROM_HAS_DN(0.00)[]; PRECEDENCE_BULK(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCPT_COUNT_TWELVE(0.00)[35]; TAGGED_RCPT(0.00)[]; FORGED_SENDER_MAILLIST(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sto.lore.kernel.org:rdns,sto.lore.kernel.org:helo,collabora.com:email,collabora.com:dkim]; R_DKIM_ALLOW(0.00)[collabora.com:s=mail]; FROM_NEQ_ENVFROM(0.00)[cristian.ciocaltea@collabora.com,linux-sunxi@lists.linux.dev]; TAGGED_FROM(0.00)[bounces-25421-noreply=patchwork.local]; R_SPF_ALLOW(0.00)[+ip4:172.232.135.74:c]; DKIM_TRACE(0.00)[collabora.com:+]; TO_DN_SOME(0.00)[]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[148.251.105.195:received,100.64.0.241:received,100.90.174.1:received]; ASN(0.00)[asn:63949, ipnet:172.232.128.0/19, country:SG]; DMARC_POLICY_ALLOW(0.00)[collabora.com,none]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; MID_RHS_MATCH_FROM(0.00)[]; FREEMAIL_TO(0.00)[linux.intel.com,kernel.org,suse.de,gmail.com,ffwll.ch,raspberrypi.com,intel.com,linaro.org,ideasonboard.com,kwiboo.se,bootlin.com,sholland.org,igalia.com,rock-chips.com,sntech.de,collabora.com,nxp.com,baylibre.com,gmx.de]; RCVD_TLS_LAST(0.00)[]; MIME_TRACE(0.00)[0:+]; RBL_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[172.232.135.74:from] X-Rspamd-Queue-Id: C1AFF1C002D 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?= |
| Series |
Add HDMI 2.0 support to DW HDMI QP TX
|
|
Commit Message
Cristian Ciocaltea
Sept. 1, 2026, 6:50 p.m. UTC
The system-sleep PM callbacks fetch the driver state via
dev_get_drvdata() and dereference it unconditionally. However, the
platform device is bound by ->probe(), which merely registers a
component, hence the callbacks may well run when no valid state is
available:
- Before the aggregate driver calls ->bind(), e.g. when the system
suspends while probing is still deferred waiting for the VOP,
dev_get_drvdata() returns NULL.
- After ->unbind(), or when ->bind() fails past platform_set_drvdata(),
drvdata is left pointing to memory obtained via drmm_kzalloc(), which
is released together with the DRM device, while this platform device
remains bound and PM-capable.
Publish the driver data only after ->bind() completes successfully, and
clear it in ->unbind(). This ensures that a non-NULL drvdata always
represents live state, allowing each PM callback to rely on a single
NULL check.
Fixes: 128a9bf8ace2 ("drm/rockchip: Add basic RK3588 HDMI output support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260702151550.8E14D1F000E9@smtp.kernel.org/
Closes: https://lore.kernel.org/all/20260723014811.1F9F01F000E9@smtp.kernel.org/
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
Comments
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [High] Using `devm_*` APIs in the component `bind` callback coupled with a `drmm_` allocated context causes resource leaks on bind retries and use-after-free vulnerabilities. -- commit 78a45b3c5f7568988aeb46e28d8dcd405d6b493f Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> drm/rockchip: dw_hdmi_qp: Fix invalid drvdata access in PM ops This commit defers publishing the driver data until the component bind callback completes successfully, and clears it during unbind. This ensures that the PM callbacks can rely on a single null check to avoid accessing invalid or freed state. Closes: https://lore.kernel.org/all/20260702151550.8E14D1F000E9@smtp.kernel.org/ Closes: https://lore.kernel.org/all/20260723014811.1F9F01F000E9@smtp.kernel.org/ > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c > index 9c4cf68d79d50..646a4cb968309 100644 > --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c > +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c > @@ -683,8 +683,6 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, > if (ret) > return dev_err_probe(hdmi->dev, ret, "Failed to init encoder"); > > - platform_set_drvdata(pdev, hdmi); > - [Severity: High] This is a pre-existing issue, but does using devm_ allocations in a component bind callback risk resource leaks and use-after-free bugs? The component bind function registers resources like clocks, GPIO, PHY, and IRQs using devm_ APIs on the component's platform device (dev). Since these resources are tied to the platform device's lifetime, they won't be freed when the component is unbound or when bind fails and is retried. For example, earlier in dw_hdmi_qp_rockchip_bind(): ret = devm_request_threaded_irq(dev, hdmi->hpd_irq, cfg->ctrl_ops->hardirq_callback, cfg->ctrl_ops->irq_callback, IRQF_NO_AUTOEN, "dw-hdmi-qp-hpd", hdmi); This registers the IRQ against the platform device's lifetime, but passes the hdmi pointer as context. The hdmi structure is allocated using drmm_kzalloc(), which ties it to the DRM master device's lifetime. If the DRM master is unbound or fails to probe, hdmi is freed, but the IRQ remains registered. If an interrupt fires after the master is unbound, can the active IRQ handler in dw_hdmi_qp_rk3588_irq() dereference the freed hdmi pointer? Furthermore, do error paths after IRQ registration return without canceling the delayed work or freeing the devm_ resources, accumulating leaks on repeated bind failures? > hdmi->hdmi = dw_hdmi_qp_bind(pdev, encoder, &plat_data); > if (IS_ERR(hdmi->hdmi)) > return dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmi), [ ... ] > @@ -704,6 +704,8 @@ static void dw_hdmi_qp_rockchip_unbind(struct device *dev, > { > struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); > > + dev_set_drvdata(dev, NULL); > + > cancel_delayed_work_sync(&hdmi->hpd_work); > } [Severity: High] This is also a pre-existing issue, but does cleaning up the delayed work here still leave the IRQ registered against the platform device? Because devm_request_threaded_irq() was used, the IRQ isn't freed during unbind. Could a subsequent interrupt trigger a use-after-free by queuing the work embedded within the already freed hdmi struct?
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 9c4cf68d79d5..646a4cb96830 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -683,8 +683,6 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, if (ret) return dev_err_probe(hdmi->dev, ret, "Failed to init encoder"); - platform_set_drvdata(pdev, hdmi); - hdmi->hdmi = dw_hdmi_qp_bind(pdev, encoder, &plat_data); if (IS_ERR(hdmi->hdmi)) return dev_err_probe(hdmi->dev, PTR_ERR(hdmi->hdmi), @@ -695,6 +693,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, return dev_err_probe(hdmi->dev, PTR_ERR(connector), "Failed to init bridge connector\n"); + platform_set_drvdata(pdev, hdmi); + return 0; } @@ -704,6 +704,8 @@ static void dw_hdmi_qp_rockchip_unbind(struct device *dev, { struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); + dev_set_drvdata(dev, NULL); + cancel_delayed_work_sync(&hdmi->hpd_work); } @@ -726,7 +728,8 @@ static int __maybe_unused dw_hdmi_qp_rockchip_suspend(struct device *dev) { struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); - dw_hdmi_qp_suspend(dev, hdmi->hdmi); + if (hdmi) + dw_hdmi_qp_suspend(dev, hdmi->hdmi); return 0; } @@ -735,6 +738,9 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) { struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); + if (!hdmi) + return 0; + hdmi->ctrl_ops->io_init(hdmi); dw_hdmi_qp_resume(dev, hdmi->hdmi);