[PATCH] usb: gadget: f_fs: fix use-after-free in ffs_func_unbind

Shuangpeng Bai <[email protected]>
Newsgroups org.kernel.vger.linux-usb,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
ffs_func_unbind() continues to access ffs after calling
functionfs_unbind(), including taking ffs->eps_lock for endpoint cleanup.
However, functionfs_unbind() drops the binding reference to ffs.

A concurrent FunctionFS unmount can drop the independent superblock
reference. Either put can then release the final reference and free ffs
before ffs_func_unbind() finishes its endpoint cleanup.

Take a temporary ffs reference for the duration of ffs_func_unbind() and
drop it only after all post-unbind cleanup is complete.

Fixes: a3058a5d82e2 ("usb: gadget: f_fs: remove redundant ffs_data_get()")
Cc: [email protected]
Signed-off-by: Shuangpeng Bai <[email protected]>
---
 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 44218be1e676..8acad4564b6c 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -4089,6 +4089,9 @@ static void ffs_func_unbind(struct usb_configuration *c,
 	unsigned count = ffs->eps_count;
 	unsigned long flags;
 
+	/* Keep ffs alive until all post-unbind cleanup is complete. */
+	ffs_data_get(ffs);
+
 	if (ffs->func == func) {
 		ffs_func_eps_disable(func);
 		ffs->func = NULL;
@@ -4122,6 +4125,7 @@ static void ffs_func_unbind(struct usb_configuration *c,
 	func->function.ssp_descriptors = NULL;
 	func->interfaces_nums = NULL;
 
+	ffs_data_put(ffs);
 }
 
 static struct usb_function *ffs_alloc(struct usb_function_instance *fi)
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.