* [PATCH v2 1/4] usb: gadget: f_fs: Initialize epfile->in early to fix endpoint direction checks
[not found] <20260619040609.4010746-1-nkapron@google.com>
@ 2026-06-19 4:06 ` Neill Kapron
2026-06-19 4:06 ` [PATCH v2 2/4] usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile Neill Kapron
1 sibling, 0 replies; 2+ messages in thread
From: Neill Kapron @ 2026-06-19 4:06 UTC (permalink / raw)
To: gregkh, corbet, skhan, Paul Cercueil, Simona Vetter,
Christian König
Cc: linux-usb, linux-doc, linux-kernel, kernel-team, Neill Kapron,
stable
When parsing endpoint descriptors, ffs_data_got_descs() generates the
eps_addrmap which contains the endpoint direction. However, epfile->in
was previously only populated in ffs_func_eps_enable() which executes
upon USB host connection. As a result, early userspace ioctls like
FUNCTIONFS_DMABUF_ATTACH that run before the host connects would see
epfile->in as 0, leading to incorrect DMA directions.
By moving the initialization to ffs_epfiles_create(), epfile->in is
accurate before userspace opens the endpoint files.
Fixes: 7b07a2a7ca02 ("usb: gadget: functionfs: Add DMABUF import interface")
Cc: stable@vger.kernel.org
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
---
drivers/usb/gadget/function/f_fs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 75912ce6ab55..38e36faefe92 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -2364,6 +2364,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs)
sprintf(epfile->name, "ep%02x", ffs->eps_addrmap[i]);
else
sprintf(epfile->name, "ep%u", i);
+ epfile->in = (ffs->eps_addrmap[i] & USB_ENDPOINT_DIR_MASK) ? 1 : 0;
err = ffs_sb_create_file(ffs->sb, epfile->name,
epfile, &ffs_epfile_operations);
if (err) {
@@ -2453,7 +2454,6 @@ static int ffs_func_eps_enable(struct ffs_function *func)
ret = usb_ep_enable(ep->ep);
if (!ret) {
epfile->ep = ep;
- epfile->in = usb_endpoint_dir_in(ep->ep->desc);
epfile->isoc = usb_endpoint_xfer_isoc(ep->ep->desc);
} else {
break;
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread* [PATCH v2 2/4] usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile
[not found] <20260619040609.4010746-1-nkapron@google.com>
2026-06-19 4:06 ` [PATCH v2 1/4] usb: gadget: f_fs: Initialize epfile->in early to fix endpoint direction checks Neill Kapron
@ 2026-06-19 4:06 ` Neill Kapron
1 sibling, 0 replies; 2+ messages in thread
From: Neill Kapron @ 2026-06-19 4:06 UTC (permalink / raw)
To: gregkh, corbet, skhan, Felipe Balbi, Michal Nazarewicz
Cc: linux-usb, linux-doc, linux-kernel, kernel-team, Neill Kapron,
stable
Currently, ffs_epfile_release unconditionally frees the endpoint's
read_buffer when a file descriptor is closed. If userspace explicitly
opens the endpoint multiple times and closes one, the read_buffer is
destroyed. This can lead to silent data loss if other file descriptors
are still actively reading from the endpoint.
By tying the lifetime of the read_buffer to the ffs_epfile structure itself
(which is destroyed when the functionfs instance is torn down in
ffs_epfiles_destroy), we eliminate the brittle dependency on open/release
calls while correctly matching the conceptual lifetime of unread data on
the hardware endpoint.
Fixes: 9353afbbfa7b ("usb: gadget: f_fs: buffer data from ‘oversized’ OUT requests")
Cc: stable@vger.kernel.org
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Neill Kapron <nkapron@google.com>
---
drivers/usb/gadget/function/f_fs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 38e36faefe92..374ab36eaaa3 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1374,7 +1374,6 @@ ffs_epfile_release(struct inode *inode, struct file *file)
mutex_unlock(&epfile->dmabufs_mutex);
- __ffs_epfile_read_buffer_free(epfile);
ffs_data_closed(epfile->ffs);
return 0;
@@ -2390,6 +2389,7 @@ static void ffs_epfiles_destroy(struct super_block *sb,
for (; count; --count, ++epfile) {
BUG_ON(mutex_is_locked(&epfile->mutex));
+ __ffs_epfile_read_buffer_free(epfile);
simple_remove_by_name(root, epfile->name, clear_one);
}
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread