[PATCH] drm/bridge: anx78xx: fix potential use-after-free on device removal
From: Fan Wu
Date: Thu Aug 20 2026 - 00:49:18 EST
The HPD and INTP interrupts are requested with
devm_request_threaded_irq(), so they stay armed until the devm cleanup
runs after ->remove() has returned. anx78xx_i2c_remove() unregisters
the dummy i2c clients and frees the cached EDID before that, and both
threaded handlers access those clients through their regmaps, so a
handler running in this window can cause a use-after-free, or a
double-free of the EDID when a cable is unplugged.
Free both interrupts with devm_free_irq() before the dummy clients are
unregistered. free_irq() waits for a running threaded handler to
finish, so the handlers can no longer race with the teardown. The
probe error path taken when the INTP request fails unregisters the
dummy clients with the HPD interrupt still armed; free it there too.
This issue was found by an in-house static analysis tool.
Fixes: 0647e7dd3f7a ("drm/bridge: Add Analogix anx78xx support")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@xxxxxxxxxx>
---
drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index ba0fc149a9e7..a5f4ecb96498 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -1304,6 +1304,7 @@ static int anx78xx_i2c_probe(struct i2c_client *client)
"anx78xx-intp", anx78xx);
if (err) {
DRM_ERROR("Failed to request INTP threaded IRQ: %d\n", err);
+ devm_free_irq(&client->dev, pdata->hpd_irq, anx78xx);
goto err_poweroff;
}
@@ -1327,6 +1328,14 @@ static void anx78xx_i2c_remove(struct i2c_client *client)
{
struct anx78xx *anx78xx = i2c_get_clientdata(client);
+ /*
+ * The threaded IRQ handlers access the dummy I2C clients through
+ * regmap and may free the cached EDID, so stop them before those
+ * resources are freed below.
+ */
+ devm_free_irq(&client->dev, anx78xx->pdata.hpd_irq, anx78xx);
+ devm_free_irq(&client->dev, anx78xx->pdata.intp_irq, anx78xx);
+
drm_bridge_remove(&anx78xx->bridge);
unregister_i2c_dummy_clients(anx78xx);
--
2.34.1