The Linux Kernel Mailing List
 help / color / mirror / Atom feed
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 :)

  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