| From 8df672bfe3ec2268c2636584202755898e547173 Mon Sep 17 00:00:00 2001 |
| From: Oliver Neukum <oneukum@suse.com> |
| Date: Wed, 4 Mar 2026 14:01:12 +0100 |
| Subject: usb: class: cdc-wdm: fix reordering issue in read code path |
| |
| From: Oliver Neukum <oneukum@suse.com> |
| |
| commit 8df672bfe3ec2268c2636584202755898e547173 upstream. |
| |
| Quoting the bug report: |
| |
| 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]. |
| |
| Fix it by using WRITE_ONCE and memory barriers. |
| |
| Fixes: afba937e540c9 ("USB: CDC WDM driver") |
| Cc: stable <stable@kernel.org> |
| Signed-off-by: Oliver Neukum <oneukum@suse.com> |
| Closes: https://lore.kernel.org/linux-usb/CALbr=LbrUZn_cfp7CfR-7Z5wDTHF96qeuM=3fO2m-q4cDrnC4A@mail.gmail.com/ |
| Reported-by: Gui-Dong Han <hanguidong02@gmail.com> |
| Reviewed-by: Gui-Dong Han <hanguidong02@gmail.com> |
| Link: https://patch.msgid.link/20260304130116.1721682-1-oneukum@suse.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/usb/class/cdc-wdm.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/usb/class/cdc-wdm.c |
| +++ b/drivers/usb/class/cdc-wdm.c |
| @@ -212,7 +212,8 @@ static void wdm_in_callback(struct urb * |
| /* we may already be in overflow */ |
| if (!test_bit(WDM_OVERFLOW, &desc->flags)) { |
| memmove(desc->ubuf + desc->length, desc->inbuf, length); |
| - desc->length += length; |
| + smp_wmb(); /* against wdm_read() */ |
| + WRITE_ONCE(desc->length, desc->length + length); |
| } |
| } |
| skip_error: |
| @@ -519,6 +520,7 @@ static ssize_t wdm_read |
| return -ERESTARTSYS; |
| |
| cntr = READ_ONCE(desc->length); |
| + smp_rmb(); /* against wdm_in_callback() */ |
| if (cntr == 0) { |
| desc->read = 0; |
| retry: |