* FAILED: patch "[PATCH] usb: gadget: f_fs: Fix Use-After-Free in AIO error path" failed to apply to 6.18-stable tree
@ 2026-09-03 12:41 gregkh
2026-09-04 14:29 ` [PATCH 6.18.y 1/2] USB: gadget: ffs: fix mm lifetime handling Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-09-03 12:41 UTC (permalink / raw)
To: nkapron, gregkh, xingyuj; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x e78dcb1f7ec271449c54984dc90c62a5ba272de7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026090331-width-covenant-cd4e@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e78dcb1f7ec271449c54984dc90c62a5ba272de7 Mon Sep 17 00:00:00 2001
From: Neill Kapron <nkapron@google.com>
Date: Fri, 24 Jul 2026 23:51:00 +0000
Subject: [PATCH] usb: gadget: f_fs: Fix Use-After-Free in AIO error path
In ffs_epfile_write_iter() and ffs_epfile_read_iter(), when ffs_epfile_io()
fails with an error other than -EIOCBQUEUED, the io_data structure (`p`) is
freed. However, for AIO operations, the kiocb cancel function was already
armed and kiocb->private was set to `p`.
If a concurrent cancel operation (such as sys_io_cancel()) executes after
ffs_epfile_io() fails but before the function frees `p`, a Use-After-Free
can occur when the cancellation handler accesses the freed pointer.
To securely fix this race condition, we must properly un-arm the
cancellation. Invoking `kiocb->ki_complete()` does exactly this by
acquiring `ctx->ctx_lock` and safely removing the kiocb from the active
sequence. In doing so, it ensures that a parallel io_cancel can no longer
discover the kiocb, effectively closing the race window.
We then return -EIOCBQUEUED to notify the VFS layer that the kiocb has been
consumed and it should avoid attempting to complete the request again or
triggering subsequent completion handlers.
Fixes: de2080d41b5d ("gadget/function/f_fs.c: close leaks")
Cc: stable@vger.kernel.org
Reported-by: Xingyu Jin <xingyuj@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
Link: https://patch.msgid.link/20260724235100.106011-1-nkapron@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index cfa05266e551..43962e05eacf 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1296,8 +1296,10 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*from = p->data;
}
@@ -1345,9 +1347,11 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p->to_free);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*to = p->data;
}
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 6.18.y 1/2] USB: gadget: ffs: fix mm lifetime handling
2026-09-03 12:41 FAILED: patch "[PATCH] usb: gadget: f_fs: Fix Use-After-Free in AIO error path" failed to apply to 6.18-stable tree gregkh
@ 2026-09-04 14:29 ` Sasha Levin
2026-09-04 14:29 ` [PATCH 6.18.y 2/2] usb: gadget: f_fs: Fix Use-After-Free in AIO error path Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-09-04 14:29 UTC (permalink / raw)
To: stable; +Cc: Gabriel Prostitis, Greg Kroah-Hartman, Sasha Levin
From: Gabriel Prostitis <prostitisgabriel@gmail.com>
[ Upstream commit 5eb5c72c72fef76cb765ef1669b62b6a3ba1bfc8 ]
io_data stores a pointer to the submitting task's mm_struct,
but does not currently hold a reference to it while async
requests are pending.
This can result in a use-after-free if the task exits before
completion handling finishes.
Take a reference with mmgrab() when queuing the read request
and release it with mmdrop() on request completion.
Reported-by: Gabriel Prostitis <prostitisgabriel@gmail.com>
Signed-off-by: Gabriel Prostitis <prostitisgabriel@gmail.com>
Link: https://patch.msgid.link/20260601-mm-uaf-fix-v2-1-3c942a707bce@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: e78dcb1f7ec2 ("usb: gadget: f_fs: Fix Use-After-Free in AIO error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 3116060977185..a00bf66bdf878 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -857,9 +857,15 @@ static void ffs_user_copy_worker(struct work_struct *work)
bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
if (io_data->read && ret > 0) {
- kthread_use_mm(io_data->mm);
- ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
- kthread_unuse_mm(io_data->mm);
+ if (mmget_not_zero(io_data->mm)) {
+ kthread_use_mm(io_data->mm);
+ ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
+ kthread_unuse_mm(io_data->mm);
+ mmput(io_data->mm);
+ } else {
+ ret = -EFAULT;
+ }
+ mmdrop(io_data->mm);
}
io_data->kiocb->ki_complete(io_data->kiocb, ret);
@@ -1240,16 +1246,20 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
kiocb->private = p;
- if (p->aio)
+ if (p->aio) {
+ mmgrab(p->mm);
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
+ }
res = ffs_epfile_io(kiocb->ki_filp, p);
if (res == -EIOCBQUEUED)
return res;
- if (p->aio)
+ if (p->aio) {
+ mmdrop(p->mm);
kfree(p);
- else
+ } else {
*from = p->data;
+ }
return res;
}
@@ -1284,14 +1294,17 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
kiocb->private = p;
- if (p->aio)
+ if (p->aio) {
+ mmgrab(p->mm);
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
+ }
res = ffs_epfile_io(kiocb->ki_filp, p);
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
+ mmdrop(p->mm);
kfree(p->to_free);
kfree(p);
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 6.18.y 2/2] usb: gadget: f_fs: Fix Use-After-Free in AIO error path
2026-09-04 14:29 ` [PATCH 6.18.y 1/2] USB: gadget: ffs: fix mm lifetime handling Sasha Levin
@ 2026-09-04 14:29 ` Sasha Levin
0 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-09-04 14:29 UTC (permalink / raw)
To: stable; +Cc: Neill Kapron, Xingyu Jin, Greg Kroah-Hartman, Sasha Levin
From: Neill Kapron <nkapron@google.com>
[ Upstream commit e78dcb1f7ec271449c54984dc90c62a5ba272de7 ]
In ffs_epfile_write_iter() and ffs_epfile_read_iter(), when ffs_epfile_io()
fails with an error other than -EIOCBQUEUED, the io_data structure (`p`) is
freed. However, for AIO operations, the kiocb cancel function was already
armed and kiocb->private was set to `p`.
If a concurrent cancel operation (such as sys_io_cancel()) executes after
ffs_epfile_io() fails but before the function frees `p`, a Use-After-Free
can occur when the cancellation handler accesses the freed pointer.
To securely fix this race condition, we must properly un-arm the
cancellation. Invoking `kiocb->ki_complete()` does exactly this by
acquiring `ctx->ctx_lock` and safely removing the kiocb from the active
sequence. In doing so, it ensures that a parallel io_cancel can no longer
discover the kiocb, effectively closing the race window.
We then return -EIOCBQUEUED to notify the VFS layer that the kiocb has been
consumed and it should avoid attempting to complete the request again or
triggering subsequent completion handlers.
Fixes: de2080d41b5d ("gadget/function/f_fs.c: close leaks")
Cc: stable@vger.kernel.org
Reported-by: Xingyu Jin <xingyuj@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
Link: https://patch.msgid.link/20260724235100.106011-1-nkapron@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_fs.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index a00bf66bdf878..df66441bec46f 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1255,8 +1255,10 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*from = p->data;
}
@@ -1304,9 +1306,11 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
return res;
if (p->aio) {
+ kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p->to_free);
kfree(p);
+ return -EIOCBQUEUED;
} else {
*to = p->data;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-04 14:29 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 12:41 FAILED: patch "[PATCH] usb: gadget: f_fs: Fix Use-After-Free in AIO error path" failed to apply to 6.18-stable tree gregkh
2026-09-04 14:29 ` [PATCH 6.18.y 1/2] USB: gadget: ffs: fix mm lifetime handling Sasha Levin
2026-09-04 14:29 ` [PATCH 6.18.y 2/2] usb: gadget: f_fs: Fix Use-After-Free in AIO error path Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox