[BUG] usb: cdc-wdm: Missing barriers in ad-hoc lockless buffer

From: Gui-Dong Han

Date: Wed Mar 04 2026 - 03:45:28 EST


Hello maintainers,

I would like to report a potential concurrency bug in
drivers/usb/class/cdc-wdm.c.

The driver implements an ad-hoc lockless buffer using desc->ubuf and
desc->length. In wdm_read(), the read side checks
READ_ONCE(desc->length) outside the spinlock. However, the write side
in wdm_in_callback() updates the buffer and length without WRITE_ONCE
and any memory barriers.

Due to compiler optimization or CPU out-of-order execution, the
desc->length update can be reordered before the memmove. If this
happens, wdm_read() can see the new length and call copy_to_user() on
uninitialized memory. This also violates LKMM data race rules [1].

Additionally, the driver relies heavily on set_bit() and test_bit() on
desc->flags for synchronization. These bit operations do not provide
implicit barriers, which might lead to similar ordering issues.

Proposed solutions:
1. Short-term: Add WRITE_ONCE() and smp_wmb() on the write side, and
smp_rmb() on the read side.
2. Long-term: Replace the ad-hoc buffer with kfifo. This is a classic
single-reader (holding desc->rlock) and single-writer (holding
desc->iuspin) scenario, making it a perfect fit for kfifo.

I discovered this issue while studying the driver's code. The presence
of a READ_ONCE() on the read side without a matching WRITE_ONCE() on
the write side caught my attention as a potential data race under the
LKMM. In my opinion, implementing ad-hoc lockless algorithms directly
within individual drivers is highly error-prone. To avoid these subtle
memory ordering and barrier bugs, drivers should rely on established,
well-tested kernel libraries like kfifo to handle this type of
concurrency.

I am currently trying to reproduce the issue via stress testing on
ARM64, though the race window is tight. I will also attempt a kfifo
refactoring. However, since I am not familiar with this specific
driver, I welcome anyone else to take over the kfifo conversion to
eliminate these potential bugs and simplify the code.

Thank you for your attention to this matter.

Thanks.

[1] https://elixir.bootlin.com/linux/v6.19-rc5/source/tools/memory-model/Documentation/explanation.txt#L2231