From: sashiko-bot@kernel.org
To: "Sasha Levin" <sashal@kernel.org>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH AUTOSEL 6.18-5.10] USB: gadget: inode: fix mm lifetime handling
Date: Mon, 19 Oct 2026 15:11:49 +0000 [thread overview]
Message-ID: <sashiko-outbox-177640@kernel.org> (raw)
In-Reply-To: <20261019135441.1420968-360-sashal@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] usb: gadget: inode: mmdrop() called in atomic context in ep_aio_complete()
--
commit 1034aa9a2c06c8a1a74aa881eb54ff67ca5c0fee
Author: Gabriel Prostitis <prostitisgabriel@gmail.com>
USB: gadget: inode: fix mm lifetime handling
This commit fixes a use-after-free in gadgetfs async I/O handling by pinning
the submitting task's mm_struct with mmgrab() in ep_aio() and releasing it
with mmdrop() upon request completion. It also uses mmget_not_zero() in
ep_user_copy_worker() before switching to the address space.
Link: https://patch.msgid.link/20260601-mm-uaf-fix-v2-2-3c942a707bce@gmail.com
> diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
> index 13c3da49348c5..7d201c065ae3b 100644
> --- a/drivers/usb/gadget/legacy/inode.c
> +++ b/drivers/usb/gadget/legacy/inode.c
[ ... ]
> @@ -503,6 +509,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req)
> * complete the aio request immediately.
> */
> if (priv->to_free == NULL || unlikely(req->actual == 0)) {
> + mmdrop(priv->mm);
[Severity: High]
Is it safe to call mmdrop(priv->mm) directly in ep_aio_complete()?
ep_aio() pins current->mm with mmgrab(priv->mm) for all async requests. If
the submitting task exits before the USB request completes (for example,
with io_uring or a forked process where do_exit() -> exit_mm() -> mmput()
runs before completion), priv->mm can hold the final reference on
mm->mm_count.
When the request completes and takes the immediate completion branch
(priv->to_free == NULL || unlikely(req->actual == 0)) — which occurs for
async writes, single-buffer ITER_UBUF reads where dup_iter() returns NULL,
zero-length reads, errors, disconnects, or cancellations via
ep_aio_cancel() -> usb_ep_dequeue() — ep_aio_complete() runs as the
usb_request->complete callback with interrupts disabled and while holding
spin_lock(&epdata->dev->lock):
drivers/usb/gadget/legacy/inode.c:ep_aio_complete() {
spin_lock(&epdata->dev->lock);
priv->req = NULL;
priv->epdata = NULL;
if (priv->to_free == NULL || unlikely(req->actual == 0)) {
mmdrop(priv->mm);
}
If mmdrop(priv->mm) drops the last reference, it invokes __mmdrop() from
atomic, interrupts-disabled context:
kernel/fork.c:__mmdrop() {
...
cleanup_lazy_tlbs(mm);
WARN_ON_ONCE(mm == current->active_mm);
mm_free_pgd(mm);
...
}
This appears to cause a few issues:
1. On architectures with CONFIG_MMU_LAZY_TLB_SHOOTDOWN=y,
__mmdrop() -> cleanup_lazy_tlbs() -> on_each_cpu_mask() ->
smp_call_function_many_cond() waits synchronously for cross-CPU IPIs,
triggering lockdep_assert_irqs_enabled() and WARN_ON_ONCE(!in_task()) in
kernel/smp.c and potentially deadlocking with interrupts disabled.
2. On x86, __mmdrop() -> mm_free_pgd() -> pgd_free() -> pgd_dtor() acquires
spin_lock(&pgd_lock) without disabling interrupts:
arch/x86/mm/pgtable.c:pgd_dtor() {
spin_lock(&pgd_lock);
pgd_list_del(pgd);
spin_unlock(&pgd_lock);
}
As noted in free_signal_struct() in kernel/fork.c, __mmdrop() is not safe to
call from interrupt or softirq context on x86 because taking pgd_lock can
deadlock if the interrupted context already holds pgd_lock.
3. On CONFIG_PREEMPT_RT=y, __mmdrop() acquires sleeping spinlock_t locks
while interrupts are disabled and a spinlock is held.
Should ep_aio_complete() use mmdrop_async(priv->mm) here (or avoid grabbing
priv->mm when priv->to_free == NULL, since the worker is only scheduled when
priv->to_free != NULL)?
> kfree(req->buf);
> kfree(priv->to_free);
> kfree(priv);
[ ... ]
> @@ -543,6 +550,7 @@ static ssize_t ep_aio(struct kiocb *iocb,
> priv->epdata = epdata;
> priv->actual = 0;
> priv->mm = current->mm; /* mm teardown waits for iocbs in exit_aio() */
> + mmgrab(priv->mm);
[ ... ]
> @@ -572,6 +580,7 @@ static ssize_t ep_aio(struct kiocb *iocb,
>
> fail:
> spin_unlock_irq(&epdata->dev->lock);
> + mmdrop(priv->mm);
> kfree(priv->to_free);
> kfree(priv);
> put_ep(epdata);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261019135441.1420968-360-sashal@kernel.org?part=1
next prev parent reply other threads:[~2026-10-19 15:11 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20261019135441.1420968-1-sashal@kernel.org>
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18-5.10] usb_string_copy: Use kzalloc() to avoid leaking old data Sasha Levin
2026-10-19 14:02 ` sashiko-bot
2026-10-19 13:45 ` [PATCH AUTOSEL 6.18] usb: typec: mux: tusb1046: add missing MODULE_DEVICE_TABLE() Sasha Levin
2026-10-19 14:03 ` sashiko-bot
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-6.1] thunderbolt: xdomain: Notify peers after enumeration Sasha Levin
2026-10-19 14:17 ` sashiko-bot
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: fsl_qe_udc: check qe_alloc_request() failure in ch9getstatus() Sasha Levin
2026-10-19 14:20 ` sashiko-bot
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] net: usb: qmi_wwan: add Rolling Wireless RN947R Sasha Levin
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] usb: mtu3: Fix double dereference in TP_printk Sasha Levin
2026-10-19 14:18 ` sashiko-bot
2026-10-19 13:46 ` [PATCH AUTOSEL 6.18-5.10] net: usb: rtl8150: handle link status read failures Sasha Levin
2026-10-19 14:20 ` sashiko-bot
2026-10-19 13:47 ` [PATCH AUTOSEL 6.18-5.10] usb: musb: host: clear stale RX interrupt on three-strikes error Sasha Levin
2026-10-19 14:28 ` sashiko-bot
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.10] USB: misc: uss720: Fix leak in get_1284_register Sasha Levin
2026-10-19 14:34 ` sashiko-bot
2026-10-19 13:48 ` [PATCH AUTOSEL 6.18-5.15] net: usb: cdc_ether: add quirk for AMI BMC stale link events Sasha Levin
2026-10-19 14:44 ` sashiko-bot
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] usb: misc: cypress_cy7c63: check result of IO Sasha Levin
2026-10-19 14:59 ` sashiko-bot
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18-5.10] USB: gadget: inode: fix mm lifetime handling Sasha Levin
2026-10-19 15:11 ` sashiko-bot [this message]
2026-10-19 13:50 ` [PATCH AUTOSEL 6.18] xhci: include all root port children in recovery prevention on link error Sasha Levin
2026-10-19 15:25 ` sashiko-bot
2026-10-19 13:52 ` [PATCH AUTOSEL 6.18-6.1] usb: gadget: u_audio: clean up capture endpoint on feedback failure Sasha Levin
2026-10-19 15:18 ` sashiko-bot
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=sashiko-outbox-177640@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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