From: Ingo Rohloff <ingo.rohloff@lauterbach.com>
To: gregkh@linuxfoundation.org
Cc: viro@zeniv.linux.org.uk, nkapron@google.com, me@samcday.com,
michael.bommarito@gmail.com, linux-usb@vger.kernel.org,
Ingo Rohloff <ingo.rohloff@lauterbach.com>
Subject: [PATCH 2/3] usb: gadget: f_fs: register cancellation handler only after request queueing
Date: Tue, 1 Sep 2026 14:09:07 +0200 [thread overview]
Message-ID: <20260901120908.14386-3-ingo.rohloff@lauterbach.com> (raw)
In-Reply-To: <20260901120908.14386-1-ingo.rohloff@lauterbach.com>
Call kiocb_set_cancel_fn() only after usb_ep_queue() completes
successfully.
This also undoes commit e78dcb1f7ec2 ("usb: gadget: f_fs: Fix
Use-After-Free in AIO error path"): The described error is avoided by
making sure the cancellation handler is only registered, if there is
something to cancel.
Registering the cancellation handler adds the kiocb to the context's
active request list (active_reqs in aio.c). If usb_ep_queue() fails, the
request was never actually submitted to the hardware, which means the
request is not active. The aio framework already deals with calling the
completion function ki_complete() automatically if you do not return
-EIOCBQUEUED.
Signed-off-by: Ingo Rohloff <ingo.rohloff@lauterbach.com>
---
drivers/usb/gadget/function/f_fs.c | 50 ++++++++++++------------------
1 file changed, 20 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 76fba3085664..9dec09d06ca9 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1014,8 +1014,21 @@ static struct ffs_ep *ffs_epfile_wait_ep(struct ffs_epfile *epfile, struct file
return ep;
}
-static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
+static int ffs_aio_cancel(struct kiocb *kiocb)
{
+ struct ffs_io_data *io_data = kiocb->private;
+ int value;
+
+ if (!io_data || !io_data->ep || !io_data->req)
+ return -EINVAL;
+
+ value = usb_ep_dequeue(io_data->ep, io_data->req);
+ return value;
+}
+
+static ssize_t ffs_epfile_io(struct kiocb *kiocb, struct ffs_io_data *io_data)
+{
+ struct file *file = kiocb->ki_filp;
struct ffs_epfile *epfile = file->private_data;
struct usb_request *req;
struct ffs_ep *ep;
@@ -1227,6 +1240,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
* by ffs_user_copy_worker.
*/
data = NULL;
+ kiocb->private = io_data;
+ kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
error_lock:
spin_unlock_irq(&epfile->ffs->eps_lock);
@@ -1266,19 +1281,6 @@ ffs_epfile_open(struct inode *inode, struct file *file)
return stream_open(inode, file);
}
-static int ffs_aio_cancel(struct kiocb *kiocb)
-{
- struct ffs_io_data *io_data = kiocb->private;
- int value;
-
- if (io_data && io_data->ep && io_data->req)
- value = usb_ep_dequeue(io_data->ep, io_data->req);
- else
- value = -EINVAL;
-
- return value;
-}
-
static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
{
struct ffs_io_data io_data, *p = &io_data;
@@ -1299,21 +1301,15 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
p->data = *from;
p->mm = current->mm;
- 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);
+ res = ffs_epfile_io(kiocb, p);
if (res == -EIOCBQUEUED)
return res;
if (p->aio) {
- kiocb->ki_complete(kiocb, res);
mmdrop(p->mm);
kfree(p);
- return -EIOCBQUEUED;
} else {
*from = p->data;
}
@@ -1349,23 +1345,17 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
}
p->mm = current->mm;
- 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);
+ res = ffs_epfile_io(kiocb, p);
if (res == -EIOCBQUEUED)
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.55.0
next prev parent reply other threads:[~2026-09-01 12:17 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 12:09 [PATCH 0/3] usb: gadget: f_fs: cancellation and mm fixes Ingo Rohloff
2026-09-01 12:09 ` [PATCH 1/3] usb: gadget: f_fs: simplify error handling using goto Ingo Rohloff
2026-09-01 12:09 ` Ingo Rohloff [this message]
2026-09-01 12:09 ` [PATCH 3/3] usb: gadget: f_fs: Fix mmgrab()/mmdrop() balance Ingo Rohloff
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=20260901120908.14386-3-ingo.rohloff@lauterbach.com \
--to=ingo.rohloff@lauterbach.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
--cc=me@samcday.com \
--cc=michael.bommarito@gmail.com \
--cc=nkapron@google.com \
--cc=viro@zeniv.linux.org.uk \
/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