Bug 2426258 (CVE-2022-50833)

Summary: CVE-2022-50833 kernel: Bluetooth: use hdev->workqueue when queuing hdev->{cmd,ncmd}_timer works
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security DevOps Team <prodsec-dev>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
n the Linux kernel’s Bluetooth subsystem there is a flaw in the way Bluetooth HCI work items are queued. Under certain conditions, work associated with command timeouts (hdev->{cmd,ncmd}_timer) could be scheduled on the wrong workqueue while the intended workqueue is being drained. This occurs because the queuing logic did not fully account for workqueue destruction and lacked proper synchronization. An unprivileged local user interacting with Bluetooth interfaces may be able to trigger a system crash or denial of service by causing this improper scheduling
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2025-12-30 13:19:56 UTC
In the Linux kernel, the following vulnerability has been resolved:

Bluetooth: use hdev->workqueue when queuing hdev->{cmd,ncmd}_timer works

syzbot is reporting attempt to schedule hdev->cmd_work work from system_wq
WQ into hdev->workqueue WQ which is under draining operation [1], for
commit c8efcc2589464ac7 ("workqueue: allow chained queueing during
destruction") does not allow such operation.

The check introduced by commit 877afadad2dce8aa ("Bluetooth: When HCI work
queue is drained, only queue chained work") was incomplete.

Use hdev->workqueue WQ when queuing hdev->{cmd,ncmd}_timer works because
hci_{cmd,ncmd}_timeout() calls queue_work(hdev->workqueue). Also, protect
the queuing operation with RCU read lock in order to avoid calling
queue_delayed_work() after cancel_delayed_work() completed.