CVE-2026-89738

usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed

State
Published
Severity
7.8 High
Published
Sep 11, 2026
Updated
Oct 30, 2026
Reserved
Sep 11, 2026

Read the record on cve.org

Description

In the Linux kernel, the following vulnerability has been resolved:

usb: gadget: at91_udc: drain polled-VBUS timer/work before udc is freed

In polled-VBUS mode (board.vbus_pin && board.vbus_polled), probe arms a self-restarting cycle: at91_vbus_timer() schedules vbus_timer_work, and at91_vbus_timer_work() calls at91_vbus_update() and re-arms the timer via mod_timer(). Both recover the same udc through container_of and dereference it on every iteration.

Neither teardown path cancels this cycle. udc is devm-allocated, so it is freed after at91udc_remove() returns, and is likewise freed when probe fails and devres runs. A timer callback or work item that is pending or running at either point dereferences the freed udc.

Add at91_udc_shutdown_vbus_timer() and call it from at91udc_remove() and from the usb_add_gadget_udc() failure path in probe; the remaining probe error paths fail before the timer is armed. timer_shutdown_sync() waits for a running callback and clears timer->function, which makes the work handler's mod_timer() a permanent no-op; cancel_work_sync() then drains any pending or running work whose re-arm attempt now does nothing. The timer must be shut down first, since cancelling the work alone would let the timer re-queue it. The guard mirrors probe: in IRQ mode the timer and work_struct are never initialized.

This does not require a fault; a normal driver unbind can interleave with an already queued work item.

This issue was found by an in-house static analysis tool.

Scores

CVSSScoreVectorSource
3.17.8 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HLinux

Weaknesses

The record names no weakness.

Affected Products

ProductVersions
LinuxLinux
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before 2440ce54b8c4c8aa6963c181eb56164a466fbe1cAffected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before 1674e34fe61ad3f5585dc833ba6bb6522912e6a5Affected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before 723d73b245843d4fff4c3f42e857c78c2b2d414eAffected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before a2a602cb1e28d76a5398cec3fa21b0110385f501Affected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before 51a311eb97e91ce1aed3005cb71ccb2e30f8cce8Affected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before 557ef547d49ff5e6026a4d39bdd3113bd81d7688Affected
  • 4037242c4f5ff77afe61bf07ca1e8a99490219e5 to before c27d13ce4bab80fbdf6523928071b6c24b37606cAffected
LinuxLinux
  • 2.6.36Affected
  • before 2.6.36Not affected
  • 5.15.224 through 5.15.*Not affected
  • 6.1.191 through 6.1.*Not affected
  • 6.6.160 through 6.6.*Not affected
  • 6.12.109 through 6.12.*Not affected
  • 6.18.50 through 6.18.*Not affected
  • 7.2.4 through 7.2.*Not affected
  • 7.3 and laterNot affected

References

Every record here comes from the CVE Program’s CVE List. © 1999–2026 The MITRE Corporation. CVE is a registered trademark of The MITRE Corporation. The records are reproduced under the CVE Program terms of use.