[PATCH] usb: gadget: f_mass_storage: reject relative paths to fix sb_writers deadlock
From: Xue Lei
Date: Wed Jul 29 2026 - 06:41:40 EST
A deadlock can occur when writing a relative path to the mass_storage
lun file attribute while the process's CWD is on the same configfs
mount:
write(configfs_fd, "relative_path", ...)
-> vfs_write()
-> file_start_write() -- acquires sb_writers (configfs sb)
-> configfs_write_iter()
-> fsg_store_file()
-> fsg_lun_open()
-> filp_open("relative_path", O_RDWR, ...)
-> path_openat()
-> open_last_lookups()
-> mnt_want_write() -- tries to acquire same sb_writers
*** DEADLOCK ***
This happens because filp_open() resolves relative paths against the
task's CWD. If the CWD is on the same configfs superblock, path_openat()
calls mnt_want_write() which calls sb_start_write() on the same
superblock, causing a recursive lock acquisition that can deadlock
during filesystem freeze.
Backing file paths for mass_storage LUNs should always be absolute
paths pointing to block devices or regular files. Reject relative
paths early in fsg_store_file() to prevent this deadlock.
Reported-by: syzbot+4c9318af45f0bf2af153@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=4c9318af45f0bf2af153
Fixes: ef0aa4b92cf1 ("usb: gadget: f_mass_storage: add configfs support")
Signed-off-by: Xue Lei <Xue.Lei@xxxxxxxxxxxxx>
---
drivers/usb/gadget/function/storage_common.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/usb/gadget/function/storage_common.c b/drivers/usb/gadget/function/storage_common.c
index 75831f2c7abe..d45c7a34df99 100644
--- a/drivers/usb/gadget/function/storage_common.c
+++ b/drivers/usb/gadget/function/storage_common.c
@@ -448,6 +448,12 @@ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
if (count > 0 && buf[count-1] == '\n')
((char *) buf)[count-1] = 0; /* Ugh! */
+ /* Reject relative paths to prevent sb_writers deadlock when
+ * CWD is on the same filesystem (e.g., configfs).
+ */
+ if (count > 0 && buf[0] && buf[0] != '/')
+ return -EINVAL;
+
/* Load new medium */
down_write(filesem);
if (count > 0 && buf[0]) {
--
2.49.1