From: Greg KH <gregkh@linuxfoundation.org>
To: Kanishka De Silva <kpskanna1915@gmail.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC] usb: adutux: fix unlocked read_buffer_length write in adu_open() (data race)
Date: Mon, 13 Jul 2026 07:15:15 +0200 [thread overview]
Message-ID: <2026071358-illusion-basics-1146@gregkh> (raw)
In-Reply-To: <CAKJ0_Ldatt+6_q_Sudg8nCnJLz5Vc8eihK9O6mwKh7tKBZm8iw@mail.gmail.com>
On Mon, Jul 13, 2026 at 10:15:05AM +0530, Kanishka De Silva wrote:
> Hi Greg,
>
> While auditing drivers/usb/misc/adutux.c in Linux 7.1.3, I found that
> adu_open() writes dev->read_buffer_length without holding
> dev->buflock, while every other path that touches this field
> (adu_interrupt_in_callback() and adu_read()) correctly takes buflock
> as documented in the locking comment at the top of the file:
>
> * The locking scheme is a vanilla 3-lock:
> * adu_device.buflock: A spinlock, covers what IRQs touch.
>
> adu_open() (drivers/usb/misc/adutux.c:268):
>
> /* initialize in direction */
> dev->read_buffer_length = 0;
>
> This is reached while holding only adutux_mutex, not buflock. Meanwhile:
>
> - adu_interrupt_in_callback() (lines 165-196) holds buflock while
> reading and incrementing read_buffer_length from IRQ context.
> - adu_read() (lines 394-404) holds buflock while reading, swapping,
> and zeroing read_buffer_length.
>
> So two different locks (adutux_mutex vs buflock) are used to protect
> the same field, which is a textbook data race: if an IRQ callback
> increments read_buffer_length concurrently with a re-open() clearing
> it, the increment can be silently lost, corrupting buffer state.
> Repeated open/close under interrupt load can produce stale or dropped
> USB read data from the ADU device.
>
> I reproduced the race by extracting the exact code paths (locking
> primitives, field layout, and control flow) into a standalone
> userspace program and running it under ThreadSanitizer with pthreads
> simulating the IRQ callback and open() paths concurrently. TSan
> reports the expected data race between the two lock domains on
> read_buffer_length. I'm happy to send the verifier program if useful,
> though I want to be clear it's a userspace reconstruction for
> lock-discipline verification, not the compiled kernel driver itself.
>
> Suggested fix:
>
> static int adu_open(struct inode *inode, struct file *file)
> {
> + unsigned long flags;
> ...
> - dev->read_buffer_length = 0;
> + spin_lock_irqsave(&dev->buflock, flags);
> + dev->read_buffer_length = 0;
> + spin_unlock_irqrestore(&dev->buflock, flags);
>
> Impact is data corruption / stale reads on the ADU USB device class,
> not memory corruption or privilege escalation, so I'd call this Medium
> severity. Reachable by any unprivileged user who can open
> /dev/usb/adutuxN.
>
> Happy to send a proper patch with commit message if this looks correct
> to you — let me know if you'd like it in a different form.
Just send a proper patch, you never have to ask if you should do so or
not :)
next prev parent reply other threads:[~2026-07-13 5:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-13 4:45 [PATCH RFC] usb: adutux: fix unlocked read_buffer_length write in adu_open() (data race) Kanishka De Silva
2026-07-13 5:15 ` Greg KH [this message]
2026-07-13 5:37 ` [PATCH] usb: adutux: fix unlocked read_buffer_length write in adu_open() Kanishka De Silva
2026-07-13 7:25 ` [PATCH RFC] usb: adutux: fix unlocked read_buffer_length write in adu_open() (data race) Oliver Neukum
2026-07-13 7:56 ` [PATCH v2] usb: adutux: take buflock when resetting read_buffer_length in adu_open() Kanishka De Silva
2026-07-13 12:03 ` Greg KH
2026-07-13 13:48 ` Alan Stern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2026071358-illusion-basics-1146@gregkh \
--to=gregkh@linuxfoundation.org \
--cc=kpskanna1915@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.