CVE-2026-98689: thunderbolt: Don't access a DP tunnel after its DPRX read was canceled
In the Linux kernel, the following vulnerability has been resolved:
thunderbolt: Don't access a DP tunnel after its DPRX read was canceled
tbdpdprxwork() checks ->dprxcanceled before it takes tb->lock so it misses a tbdpdprxstop() that could not cancel the already running work. It then polls the DPRX capabilities and runs the callback for a tunnel that has already been torn down while the domain is suspending or going away.
This can be hit by cancelling the DPRX read from outside the ordered tb->wq: During suspend tbdisconnectandreleasedp() does just this and with a later patch tbstop() will do it as well. The latter in combination with the Apple NHI where the DPRX read never completed is how I hit this.
Check the flag with tb->lock held instead and check it again in tbdptunnelactive() because the callback runs after the lock has been dropped again.
Also clear the flag in tbdpdprxstart() so that it only ever describes the work that is currently in flight.
Affected Software
Event History
Frequently Asked Questions
When is this issue most likely to be triggered?
It can occur when a DisplayPort receiver (DPRX) read is cancelled outside the ordered Thunderbolt workqueue while the associated DP tunnel is being torn down. The described paths include system suspend, domain removal, and a later stop path; an Apple NHI configuration where the DPRX read never completed was used to reproduce it.
What condition creates the unsafe access?
The DPRX worker can check its cancellation flag before acquiring the Thunderbolt lock, allowing teardown to cancel work that is already running after that check. The worker may then poll DPRX capabilities and invoke a callback for a DP tunnel that has already been removed.
How does the fix prevent the race?
The fix checks the cancellation flag while holding the Thunderbolt lock and checks it again when determining whether the DP tunnel remains active after the lock is released. It also clears the flag when starting a DPRX read so the flag represents only work currently in flight.