summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2025-11-21 08:47:23 +0200
committerMika Westerberg <mika.westerberg@linux.intel.com>2026-05-05 13:53:46 +0200
commit138ec65b2c761f065b19d115aed2b8246fc272f5 (patch)
tree1e451c7e424a5efcbee4f20178dd35def42da09f
parent2fb199dc64056ada4aa820a68931fed60333c289 (diff)
downloadlinux-138ec65b2c761f065b19d115aed2b8246fc272f5.tar.gz
linux-138ec65b2c761f065b19d115aed2b8246fc272f5.zip
thunderbolt: Keep the domain reference while processing hotplug
We process hotplug events in a workqueue that may run after the domain has been removed by tb_domain_remove(). For example if user unloads the driver while at the same time plugging a device router we may have scheduled tb_handle_hotplug() to run. Avoid possible UAF in this case by taking the domain reference before scheduling the hotplug handler in tb_queue_hotplug(). Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-rw-r--r--drivers/thunderbolt/tb.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index c69c323e6952..34b7d18cce56 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -98,7 +98,7 @@ static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug)
if (!ev)
return;
- ev->tb = tb;
+ ev->tb = tb_domain_get(tb);
ev->route = route;
ev->port = port;
ev->unplug = unplug;
@@ -2527,6 +2527,9 @@ out:
pm_runtime_mark_last_busy(&tb->dev);
pm_runtime_put_autosuspend(&tb->dev);
+ /* Undo the refcount increased in tb_queue_hotplug() */
+ tb_domain_put(tb);
+
kfree(ev);
}