Skip to contentSkip to conversation

net/9p/usbg: fix descriptor cleanup use-after-free

PATCH In review Chengfeng Ye 3 participants 3 messages Jul 31 – Sep 13

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 net/9p/usbg: fix descriptor cleanup use-after-free

usb9pfs_free_func() frees the f_usb9pfs object before calling usb_free_all_descriptors(). The usb_function passed to the latter is embedded in the freed object, so removing the function from a gadget dereferences freed memory.

The failing teardown sequence is:

configfs unlink
usb9pfs_free_func()
kfree(usb9pfs)
usb_free_all_descriptors(f)
dereference the embedded usb_function

KASAN reported:

  BUG: KASAN: slab-use-after-free in usb_free_all_descriptors+0x138/0x190
  Read of size 8 at addr ffff888106a73088 by task poc/95
  Call Trace:
   usb_free_all_descriptors+0x138/0x190
   config_usb_cfg_unlink+0x1f0/0x2f0
   configfs_unlink+0x321/0x6f0

Free the descriptors before freeing their containing object.

Fixes a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
---
 net/9p/trans_usbg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
net/9p/trans_usbg.c +1 -2
index 419cda13a7b5..8c2f0d8592c8 100644
@@ -725,8 +725,6 @@ static void usb9pfs_free_func(struct usb_function *f)
 	struct f_usb9pfs *usb9pfs = func_to_usb9pfs(f);
 	struct f_usb9pfs_opts *opts;
 
-	kfree(usb9pfs);
-
 	opts = container_of(f->fi, struct f_usb9pfs_opts, func_inst);
 
 	mutex_lock(&opts->lock);
@@ -734,6 +732,7 @@ static void usb9pfs_free_func(struct usb_function *f)
 	mutex_unlock(&opts->lock);
 
 	usb_free_all_descriptors(f);
+	kfree(usb9pfs);
 }
 
 static int usb9pfs_set_alt(struct usb_function *f,
Acked-by on v1 1/1
#1 lore raw
Quoted 15 lines · Chengfeng Ye

usb9pfs_free_func() frees the f_usb9pfs object before calling usb_free_all_descriptors(). The usb_function passed to the latter is embedded in the freed object, so removing the function from a gadget dereferences freed memory.

The failing teardown sequence is:

configfs unlink
usb9pfs_free_func()
kfree(usb9pfs)
usb_free_all_descriptors(f)
dereference the embedded usb_function

KASAN reported:

Quoted 8 lines
  BUG: KASAN: slab-use-after-free in usb_free_all_descriptors+0x138/0x190
  Read of size 8 at addr ffff888106a73088 by task poc/95
  Call Trace:
   usb_free_all_descriptors+0x138/0x190
   config_usb_cfg_unlink+0x1f0/0x2f0
   configfs_unlink+0x321/0x6f0

Free the descriptors before freeing their containing object.

Although this is a copy of https://lore.kernel.org/all/[email protected]/
which actually came earlier than your, I like the commit message here better.

Quoted 28 lines
Fixes a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
---
 net/9p/trans_usbg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
net/9p/trans_usbg.c +1 -2
index 419cda13a7b5..8c2f0d8592c8 100644
@@ -725,8 +725,6 @@ static void usb9pfs_free_func(struct usb_function *f)
 	struct f_usb9pfs *usb9pfs = func_to_usb9pfs(f);
 	struct f_usb9pfs_opts *opts;
 
-	kfree(usb9pfs);
-
 	opts = container_of(f->fi, struct f_usb9pfs_opts, func_inst);
 
 	mutex_lock(&opts->lock);
@@ -734,6 +732,7 @@ static void usb9pfs_free_func(struct usb_function *f)
 	mutex_unlock(&opts->lock);
 
 	usb_free_all_descriptors(f);
+	kfree(usb9pfs);
 }
 
 static int usb9pfs_set_alt(struct usb_function *f,
#2 lore raw
In reply to Chengfeng Ye

Chengfeng Ye wrote on Fri, Jul 31, 2026 at 11:04:14PM +0800:

Quoted 22 lines

usb9pfs_free_func() frees the f_usb9pfs object before calling usb_free_all_descriptors(). The usb_function passed to the latter is embedded in the freed object, so removing the function from a gadget dereferences freed memory.

The failing teardown sequence is:

configfs unlink
usb9pfs_free_func()
kfree(usb9pfs)
usb_free_all_descriptors(f)
dereference the embedded usb_function

KASAN reported:

  BUG: KASAN: slab-use-after-free in usb_free_all_descriptors+0x138/0x190
  Read of size 8 at addr ffff888106a73088 by task poc/95
  Call Trace:
   usb_free_all_descriptors+0x138/0x190
   config_usb_cfg_unlink+0x1f0/0x2f0
   configfs_unlink+0x321/0x6f0
Quoted 5 lines

Free the descriptors before freeing their containing object.

Fixes a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")

Thanks for the patch, given there was another identical patch earlier but Michael preferred your commit message I've kept the original patch with your commit message, keeping you as Co-developed-by

It should get in 7.4 if I'm not hit by a bus

other mail
https://lore.kernel.org/r/[email protected]

commit as of now
https://github.com/martinetd/linux/commit/0955472fff1e9f9e410a0300136924ebc8bd7a16
(look in https://github.com/martinetd/linux/commits/9p-test if commit is gone on rebase)

Signature · 1 line
Dominique Martinet | Asmadeus