* [PATCH 00/11] net/9p/usbg: series of fixes
@ 2026-03-19 9:35 Michael Grzeschik
2026-03-19 9:35 ` [PATCH 01/11] net/9p/usbg: clear stale client pointer on close Michael Grzeschik
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Michael Grzeschik @ 2026-03-19 9:35 UTC (permalink / raw)
To: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, Greg Kroah-Hartman, Hyungjung Joo
Cc: v9fs, linux-kernel, kernel, Michael Grzeschik, stable
This series contains a bunch of patches to make the trans_usbg
interface more reliable. It adds some extra checks on critical
pathes and also solves the overall synchronisation of the daemon
with the gadget. The forwarder script also gained the daemon mode to
be run and recover any kind of disconnection.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
Hyungjung Joo (1):
net/9p/usbg: clear stale client pointer on close
Michael Grzeschik (10):
net/9p/usbg: also disable endpoints on p9_usbg_close
net/9p/usbg: set client to Disconnected on usb9pfs_disable
net/9p/usbg: always reset completion when disconnecting
net/9p/usbg: only rely on one completion
net/9p/usbg: add timeout for usbg_request
net/9p/usbg: add extra interface for status change
tools/usb/p9_fwd: catch if claim_interface is not working
tools/usb/p9_fwd: catch write or read errors on disconnect
tools/usb/p9_fwd: add daemon loop
tools/usb/p9_fwd: set new introduced alt mode 1 on interface 1
net/9p/trans_usbg.c | 211 +++++++++++++++++++++++++++++++++++++++++-----------
tools/usb/p9_fwd.py | 67 +++++++++++++----
2 files changed, 218 insertions(+), 60 deletions(-)
---
base-commit: 8a30aeb0d1b4e4aaf7f7bae72f20f2ae75385ccb
change-id: 20260128-9pfixes-442c28f40622
Best regards,
--
Michael Grzeschik <m.grzeschik@pengutronix.de>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 01/11] net/9p/usbg: clear stale client pointer on close
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
@ 2026-03-19 9:35 ` Michael Grzeschik
2026-03-19 9:35 ` [PATCH 02/11] net/9p/usbg: also disable endpoints on p9_usbg_close Michael Grzeschik
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michael Grzeschik @ 2026-03-19 9:35 UTC (permalink / raw)
To: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, Greg Kroah-Hartman, Hyungjung Joo
Cc: v9fs, linux-kernel, kernel, Michael Grzeschik, stable
From: Hyungjung Joo <jhj140711@gmail.com>
p9_usbg_close() tears down the client transport, but usb9pfs keeps
using usb9pfs->client from asynchronous TX and RX completion handlers.
A late completion can therefore dereference a client that has already
been freed during mount teardown.
Clear usb9pfs->client under usb9pfs->lock when closing the transport,
detach any pending TX request from in_req->context, and make the TX/RX
completion handlers bail out once the transport has been detached. This
keeps late completions from touching a freed or rebound p9_client.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Hyungjung Joo <jhj140711@gmail.com>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
net/9p/trans_usbg.c | 61 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 1ce70338999c8c712ba298efa88c69e6372ac40f..f7a94572013e7d1015d75fb5dbdde5eb81f7d7d0 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -149,7 +149,8 @@ static void usb9pfs_tx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_usb9pfs *usb9pfs = ep->driver_data;
struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
- struct p9_req_t *p9_tx_req = req->context;
+ struct p9_client *client;
+ struct p9_req_t *p9_tx_req;
unsigned long flags;
/* reset zero packages */
@@ -165,18 +166,25 @@ static void usb9pfs_tx_complete(struct usb_ep *ep, struct usb_request *req)
ep->name, req->status, req->actual, req->length);
spin_lock_irqsave(&usb9pfs->lock, flags);
- WRITE_ONCE(p9_tx_req->status, REQ_STATUS_SENT);
+ client = usb9pfs->client;
+ p9_tx_req = req->context;
+ req->context = NULL;
- p9_req_put(usb9pfs->client, p9_tx_req);
+ if (!client || !p9_tx_req)
+ goto unlock_complete;
- req->context = NULL;
+ WRITE_ONCE(p9_tx_req->status, REQ_STATUS_SENT);
+ p9_req_put(client, p9_tx_req);
+
+unlock_complete:
spin_unlock_irqrestore(&usb9pfs->lock, flags);
complete(&usb9pfs->send);
}
-static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
+static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs,
+ struct p9_client *client, void *buf)
{
struct p9_req_t *p9_rx_req;
struct p9_fcall rc;
@@ -202,7 +210,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
"mux %p pkt: size: %d bytes tag: %d\n",
usb9pfs, rc.size, rc.tag);
- p9_rx_req = p9_tag_lookup(usb9pfs->client, rc.tag);
+ p9_rx_req = p9_tag_lookup(client, rc.tag);
if (!p9_rx_req || p9_rx_req->status != REQ_STATUS_SENT) {
p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", rc.tag);
return NULL;
@@ -212,7 +220,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
p9_debug(P9_DEBUG_ERROR,
"requested packet size too big: %d for tag %d with capacity %zd\n",
rc.size, rc.tag, p9_rx_req->rc.capacity);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_req_put(client, p9_rx_req);
return NULL;
}
@@ -220,7 +228,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
p9_debug(P9_DEBUG_ERROR,
"No recv fcall for tag %d (req %p), disconnecting!\n",
rc.tag, p9_rx_req);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_req_put(client, p9_rx_req);
return NULL;
}
@@ -231,8 +239,10 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_usb9pfs *usb9pfs = ep->driver_data;
struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
+ struct p9_client *client;
struct p9_req_t *p9_rx_req;
unsigned int req_size = req->actual;
+ unsigned long flags;
int status = REQ_STATUS_RCVD;
if (req->status) {
@@ -241,9 +251,16 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
return;
}
- p9_rx_req = usb9pfs_rx_header(usb9pfs, req->buf);
- if (!p9_rx_req)
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ client = usb9pfs->client;
+ if (!client) {
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
return;
+ }
+
+ p9_rx_req = usb9pfs_rx_header(usb9pfs, client, req->buf);
+ if (!p9_rx_req)
+ goto out_unlock;
if (req_size > p9_rx_req->rc.capacity) {
dev_err(&cdev->gadget->dev,
@@ -257,8 +274,11 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
p9_rx_req->rc.size = req_size;
- p9_client_cb(usb9pfs->client, p9_rx_req, status);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_client_cb(client, p9_rx_req, status);
+ p9_req_put(client, p9_rx_req);
+
+out_unlock:
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
complete(&usb9pfs->received);
}
@@ -416,7 +436,9 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)
client->status = Disconnected;
else
client->status = Connected;
+ spin_lock_irq(&usb9pfs->lock);
usb9pfs->client = client;
+ spin_unlock_irq(&usb9pfs->lock);
client->trans_mod->maxsize = usb9pfs->buflen;
@@ -427,18 +449,25 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)
static void usb9pfs_clear_tx(struct f_usb9pfs *usb9pfs)
{
+ struct p9_client *client;
struct p9_req_t *req;
+ unsigned long flags;
- guard(spinlock_irqsave)(&usb9pfs->lock);
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ client = usb9pfs->client;
+ usb9pfs->client = NULL;
+ req = usb9pfs->in_req ? usb9pfs->in_req->context : NULL;
+ if (usb9pfs->in_req)
+ usb9pfs->in_req->context = NULL;
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
- req = usb9pfs->in_req->context;
- if (!req)
+ if (!req || !client)
return;
if (!req->t_err)
req->t_err = -ECONNRESET;
- p9_client_cb(usb9pfs->client, req, REQ_STATUS_ERROR);
+ p9_client_cb(client, req, REQ_STATUS_ERROR);
}
static void p9_usbg_close(struct p9_client *client)
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 02/11] net/9p/usbg: also disable endpoints on p9_usbg_close
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
2026-03-19 9:35 ` [PATCH 01/11] net/9p/usbg: clear stale client pointer on close Michael Grzeschik
@ 2026-03-19 9:35 ` Michael Grzeschik
2026-03-19 9:36 ` [PATCH 03/11] net/9p/usbg: set client to Disconnected on usb9pfs_disable Michael Grzeschik
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Michael Grzeschik @ 2026-03-19 9:35 UTC (permalink / raw)
To: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, Greg Kroah-Hartman, Hyungjung Joo
Cc: v9fs, linux-kernel, kernel, Michael Grzeschik, stable
The close function has to fully reverse the state change of 9p_create
(mount) and the potential call of set_alt(1). This includes to ensure
that the usage of the endpoints is not active any more.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
net/9p/trans_usbg.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index f7a94572013e7d1015d75fb5dbdde5eb81f7d7d0..fb05198dc2a7d604cfad2db26a63e40e632651a2 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -495,6 +495,8 @@ static void p9_usbg_close(struct p9_client *client)
mutex_lock(&usb9pfs_lock);
dev->inuse = false;
mutex_unlock(&usb9pfs_lock);
+
+ disable_usb9pfs(usb9pfs);
}
static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 03/11] net/9p/usbg: set client to Disconnected on usb9pfs_disable
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
2026-03-19 9:35 ` [PATCH 01/11] net/9p/usbg: clear stale client pointer on close Michael Grzeschik
2026-03-19 9:35 ` [PATCH 02/11] net/9p/usbg: also disable endpoints on p9_usbg_close Michael Grzeschik
@ 2026-03-19 9:36 ` Michael Grzeschik
2026-03-19 9:36 ` [PATCH 04/11] net/9p/usbg: always reset completion when disconnecting Michael Grzeschik
2026-03-22 13:49 ` [PATCH 00/11] net/9p/usbg: series of fixes Dominique Martinet
4 siblings, 0 replies; 6+ messages in thread
From: Michael Grzeschik @ 2026-03-19 9:36 UTC (permalink / raw)
To: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, Greg Kroah-Hartman, Hyungjung Joo
Cc: v9fs, linux-kernel, kernel, Michael Grzeschik, stable
This patch is setting the client status to Disconnected, when the
client is still in use. Otherwiese a disconnected usb cable would run
any use of the mount to faults.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
net/9p/trans_usbg.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index fb05198dc2a7d604cfad2db26a63e40e632651a2..6ddf6886dbadd7cdfdebb96dc767874169ccb16e 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -779,7 +779,12 @@ static int usb9pfs_set_alt(struct usb_function *f,
static void usb9pfs_disable(struct usb_function *f)
{
struct f_usb9pfs *usb9pfs = func_to_usb9pfs(f);
+ unsigned long flags;
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ if (usb9pfs->client)
+ usb9pfs->client->status = Disconnected;
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
usb9pfs_clear_tx(usb9pfs);
}
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 04/11] net/9p/usbg: always reset completion when disconnecting
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
` (2 preceding siblings ...)
2026-03-19 9:36 ` [PATCH 03/11] net/9p/usbg: set client to Disconnected on usb9pfs_disable Michael Grzeschik
@ 2026-03-19 9:36 ` Michael Grzeschik
2026-03-22 13:49 ` [PATCH 00/11] net/9p/usbg: series of fixes Dominique Martinet
4 siblings, 0 replies; 6+ messages in thread
From: Michael Grzeschik @ 2026-03-19 9:36 UTC (permalink / raw)
To: Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, Greg Kroah-Hartman, Hyungjung Joo
Cc: v9fs, linux-kernel, kernel, Michael Grzeschik, stable
When some tx or rx transfers were pending while closing the connection,
the completion handler could catch one pending completion call. To
ensure a normal start when mounting again, we have to reset the
completion and flush any pending completions.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
net/9p/trans_usbg.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 6ddf6886dbadd7cdfdebb96dc767874169ccb16e..d6391db6d5d96a1609a3405646f66d82c93d35f1 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -497,6 +497,7 @@ static void p9_usbg_close(struct p9_client *client)
mutex_unlock(&usb9pfs_lock);
disable_usb9pfs(usb9pfs);
+ reinit_completion(&usb9pfs->send);
}
static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
@@ -786,6 +787,7 @@ static void usb9pfs_disable(struct usb_function *f)
usb9pfs->client->status = Disconnected;
spin_unlock_irqrestore(&usb9pfs->lock, flags);
usb9pfs_clear_tx(usb9pfs);
+ reinit_completion(&usb9pfs->send);
}
static struct usb_function *usb9pfs_alloc(struct usb_function_instance *fi)
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 00/11] net/9p/usbg: series of fixes
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
` (3 preceding siblings ...)
2026-03-19 9:36 ` [PATCH 04/11] net/9p/usbg: always reset completion when disconnecting Michael Grzeschik
@ 2026-03-22 13:49 ` Dominique Martinet
4 siblings, 0 replies; 6+ messages in thread
From: Dominique Martinet @ 2026-03-22 13:49 UTC (permalink / raw)
To: Michael Grzeschik
Cc: Eric Van Hensbergen, Latchesar Ionkov, Christian Schoenebeck,
Greg Kroah-Hartman, Hyungjung Joo, v9fs, linux-kernel, kernel,
stable
Michael Grzeschik wrote on Thu, Mar 19, 2026 at 10:35:57AM +0100:
> This series contains a bunch of patches to make the trans_usbg
> interface more reliable. It adds some extra checks on critical
> pathes and also solves the overall synchronisation of the daemon
> with the gadget. The forwarder script also gained the daemon mode to
> be run and recover any kind of disconnection.
Thanks for the patches
I don't have much time to review right now, but I'll try to take a
look... I still haven't gotten around to figure out how to make this
work with qemu or taken the time to set it up on $work boards two years
later so I'll have to trust you on actual tests, but it can't hurt to
review.
While I'm buying time here, I'm not one to praise our new robot
overlords but since it made the news I had a look and noticed
sashiko.dev ran on the patches:
https://sashiko.dev/#/patchset/20260319-9pfixes-v1-0-c977a7433185%40pengutronix.de
From a quick look of the above there are a lot of questions raised and I
don't think it's necessarily worth the time to answer all of them, but
if you have time to skim through them and pick up anything interesting
please say so
(as far as I'm concerned the usb setup is intended for a mostly trusted
setup in the first place... But then again this patch series started
with a security concern, so where do we start considering races could be
an issue?)
Thanks,
--
Dominique Martinet | Asmadeus
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-22 13:49 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-19 9:35 [PATCH 00/11] net/9p/usbg: series of fixes Michael Grzeschik
2026-03-19 9:35 ` [PATCH 01/11] net/9p/usbg: clear stale client pointer on close Michael Grzeschik
2026-03-19 9:35 ` [PATCH 02/11] net/9p/usbg: also disable endpoints on p9_usbg_close Michael Grzeschik
2026-03-19 9:36 ` [PATCH 03/11] net/9p/usbg: set client to Disconnected on usb9pfs_disable Michael Grzeschik
2026-03-19 9:36 ` [PATCH 04/11] net/9p/usbg: always reset completion when disconnecting Michael Grzeschik
2026-03-22 13:49 ` [PATCH 00/11] net/9p/usbg: series of fixes Dominique Martinet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox