CVE-2026-64584

CVE-2026-64584

High · published August 6, 2026

CVSS v3.1
7.8
EPSS
0%
Percentile
1.6
In the wild
Unconfirmed
What it is

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

usb: gadget: f_midi: cancel pending IN work before freeing the midi object

The f_midi driver embeds a work item (midi->work) whose handler,

f_midi_in_work(), dereferences the enclosing struct f_midi through

container_of(). This work is armed from two sites: f_midi_complete(),

on a normal IN-endpoint completion, and f_midi_in_trigger(), on an ALSA

rawmidi output-stream start.

Neither f_midi_disable() nor f_midi_unbind() cancels midi->work.

f_midi_disable() only disables the endpoints and drains the in_req_fifo;

it does not synchronize the work item, and the sound card is released

asynchronously to the final free of the midi object.

The midi object is reference-counted (midi->free_ref) and is freed in

f_midi_free() only once both the usb_function reference and the rawmidi

private_data reference have been dropped. In f_midi_unbind(),

f_midi_disable() runs before the sound card is released, so while the

USB endpoints are already disabled the rawmidi device is still usable by

an open substream. A concurrent userspace write on such a substream can

reach f_midi_in_trigger() and queue midi->work again after

f_midi_disable() has returned. A work item armed this way may still be

pending when the last reference drops and f_midi_free() proceeds to

kfree(midi), letting f_midi_in_work() dereference the struct after it

has been freed, a use-after-free.

For this reason cancelling midi->work in f_midi_disable() would not be

sufficient: the ALSA trigger path can rearm the work after disable()

returns. Cancelling at the refcount-zero free site is the boundary

after which neither arming source can survive, because by then both

references that keep the midi object alive have been dropped: the USB

endpoints are already disabled and the rawmidi device has been released.

Fix this by calling cancel_work_sync(&midi->work) in the refcount-zero

block of f_midi_free(), before the embedded work_struct is freed along

with the rest of the structure. opts->lock is a sleeping mutex, so

calling cancel_work_sync() under it is permitted, and the handler takes

midi->transmit_lock rather than opts->lock, so no self-deadlock can

occur while it waits for a running instance of the work to finish.

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

The record
Technical detail
CVSS v3.1
7.8 · HIGH
Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0
Not supplied
EPSS
0.00117 · 1.6th percentile
Published
2026-08-06T12:16Z
References (8)
EPSS history
Timeline
  • 06 AUG 07:06Z
    usb: gadget: f_midi: cancel pending IN work before freeing the midi object
    cvelistv5