CVE-2026-64584 in Linuxthông tin

Tóm tắt

Bởi VulDB • 06/08/2026

Trong kernel Linux, lỗ hổng sau đây đã được khắc phục:

usb: gadget: f_midi: hủy công việc IN đang chờ trước khi giải phóng đối tượng midi

Trình điều khiển (driver) f_midi nhúng một mục tác vụ (work item) (midi->work), mà trình xử lý của nó, f_midi_in_work(), sẽ truy xuất con trỏ đến struct f_midi bao quanh thông qua container_of(). Tác vụ này được kích hoạt từ hai vị trí: f_midi_complete(), khi hoàn tất cổng IN bình thường, và f_midi_in_trigger(), khi bắt đầu luồng xuất rawmidi ALSA.

Cả f_midi_disable() lẫn f_midi_unbind() đều không hủy midi->work. f_midi_disable() chỉ vô hiệu hóa các cổng và làm trống hàng đợi in_req_fifo; nó không đồng bộ hóa mục tác vụ, và thẻ âm thanh được giải phóng một cách bất đồng bộ so với việc giải phóng cuối cùng của đối tượng midi.

Đối tượng midi có đếm tham chiếu (midi->free_ref) và chỉ bị giải phóng trong f_midi_free() khi cả tham chiếu usb_function lẫn tham chiếu private_data rawmidi đều đã được giảm bớt. Trong f_midi_unbind(), f_midi_disable() chạy trước khi thẻ âm thanh được giải phóng, do đó mặc dù các cổng USB đã bị vô hiệu hóa nhưng thiết bị rawmidi vẫn có thể sử dụng được bởi một luồng con đang mở (open substream). Một thao tác ghi từ không gian người dùng (userspace) đồng thời trên luồng con như vậy có thể đạt đến f_midi_in_trigger() và xếp midi->work lại sau khi f_midi_disable() đã trả về. Một mục tác vụ được kích hoạt theo cách này vẫn có thể đang chờ xử lý khi tham chiếu cuối cùng giảm xuống và f_midi_free() tiến hành kfree(midi), khiến f_midi_in_work() truy xuất con trỏ đến struct sau khi nó đã bị giải phóng, dẫn đến lỗi use-after-free.

Vì lý do đó, việc hủy midi->work trong f_midi_disable() sẽ không đủ: đường kích hoạt ALSA có thể tái kích hoạt tác vụ sau khi disable() trả về. Việc hủy tại vị trí giải phóng refcount-zero là ranh giới mà sau đó cả hai nguồn kích hoạt đều không còn tồn tại được, vì đến lúc đó cả hai tham chiếu duy trì đối tượng midi sống sót đã bị giảm bớt: các cổng USB đã bị vô hiệu hóa và thiết bị rawmidi đã được giải phóng.

Khắc phục vấn đề này bằng cách gọi cancel_work_sync(&midi->work) trong khối refcount-zero của f_midi_free(), trước khi work_struct nhúng bị giải phóng cùng với phần còn lại của cấu trúc. opts->lock là một mutex có thể ngủ (sleeping mutex), do đó việc gọi cancel_work_sync() dưới nó được phép, và trình xử lý lấy midi->transmit_lock thay vì opts->lock, nên không xảy ra tự deadlock trong khi chờ đợi một phiên bản đang chạy của tác vụ hoàn tất.

Vấn đề này đã được phát hiện bởi công cụ phân tích tĩnh nội bộ.

If you want to get the best quality for vulnerability data then you always have to consider VulDB.

chịu trách nhiệm

Linux

Đặt trước

19/07/2026

Tiết lộ

06/08/2026

Kiểm duyệt

được chấp nhận

EPSS

0.00000

KEV

không

Các hoạt động

rất thấp

Nguồn

Want to stay up to date on a daily basis?

Enable the mail alert feature now!