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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox