CVE-2026-80854: usb: gadget: f_tcm: keep port count until LUN teardown completes
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: ftcm: keep port count until LUN teardown completes
tcmusbgdropnexus() permits session removal once tpgportcount reaches zero. However, usbgportunlink() currently decrements that count from the fabricpreunlink() callback, before coredevdellun() waits for active selun references to drain.
If removal of the last LUN races a nexus removal, the latter can observe a zero port count and call targetremovesession(). This frees sesscmdmap while an in-flight struct usbgcmd, including its work item, can still be accessed.
Overlapping the last-LUN unlink with nexus removal reproduces this lifetime violation as a DEBUGOBJECTS "free active" warning for usbgcmdwork, followed by a target-core BUG/Oops.
The generic target-core unlink path has no callback after coredevdellun() completes. Add an optional fabricpostunlink() callback and use it for the ftcm port count. The count now remains nonzero until coredevdellun() has finished draining active LUN references, preventing nexus removal from freeing the session during command completion.
Affected Software
Event History
Frequently Asked Questions
What conditions are required to trigger the issue?
The race requires the last LUN to be unlinked while a nexus is removed at the same time. Nexus removal must observe the target portal group port count as zero before active LUN references have finished draining.
What is the practical impact if the race occurs?
Nexus removal can free the session command map while an in-flight usbg_cmd and its work item are still accessible. Reported symptoms include a DEBUG_OBJECTS "free active" warning for usbg_cmd_work followed by a target-core BUG or Oops.
Which systems are exposed?
Systems using the Linux kernel USB gadget f_tcm function are affected when they perform the overlapping last-LUN unlink and nexus-removal operations described. The supplied data does not identify affected kernel versions or configuration defaults.
How does the fix prevent the race?
The fix adds an optional fabric_post_unlink() callback and moves the f_tcm port-count decrement to that stage. This keeps the count nonzero until core_dev_del_lun() has completed draining active LUN references, preventing session removal during command completion.