[lvc-project] [PATCH] usb: gadget: uvc: fix massive leak of configfs objects
Dmitry Antipov
dmantipov at yandex.ru
Thu Oct 1 09:33:33 MSK 2026
Running on QEMU with CONFIG_USB_DUMMY_HCD=y, CONFIG_USB_G_WEBCAM=y and
dummy_hcd.num=1 command line parameter, g_webcam driver probe error like:
[ 4.653636][ T1] g_webcam gadget.0: uvc: uvc_function_bind()
[ 4.653677][ T1] g_webcam gadget.0: uvc: Unable to allocate streaming EP
[ 4.653812][ T1] udc dummy_udc.0: failed to start g_webcam: -22
[ 4.653820][ T1] g_webcam gadget.0: probe with driver g_webcam failed with error -22
produces memory leaks reported as:
[ 79.307997][ T4707] kmemleak: unreferenced object 0xffff888144a9d500 (size 192):
[ 79.308008][ T4707] kmemleak: comm "swapper/0", pid 1, jiffies 4294937600
[ 79.308011][ T4707] kmemleak: backtrace (crc d47ac4f9):
[ 79.308013][ T4707] kmemleak: __kmalloc_cache_noprof+0x316/0x640
[ 79.308030][ T4707] kmemleak: uvcg_config_create_children+0x114/0x280
[ 79.308037][ T4707] kmemleak: uvcg_attach_configfs+0x33/0x60
[ 79.308041][ T4707] kmemleak: uvc_alloc_inst+0x6f9/0xa90
[ 79.308045][ T4707] kmemleak: usb_get_function_instance+0xe3/0x2f0
[ 79.308049][ T4707] kmemleak: webcam_bind+0x20/0x560
[ 79.308053][ T4707] kmemleak: composite_bind+0x1d2/0x530
[ 79.308056][ T4707] kmemleak: gadget_bind_driver+0x2ca/0x9e0
[ 79.308061][ T4707] kmemleak: really_probe+0x254/0xae0
[ 79.308067][ T4707] kmemleak: __driver_probe_device+0x1d9/0x350
[ 79.308070][ T4707] kmemleak: driver_probe_device+0x4f/0x240
[ 79.308073][ T4707] kmemleak: __driver_attach+0x339/0x600
[ 79.308076][ T4707] kmemleak: bus_for_each_dev+0x23b/0x2c0
[ 79.308080][ T4707] kmemleak: bus_add_driver+0x345/0x670
[ 79.308083][ T4707] kmemleak: driver_register+0x23a/0x320
[ 79.308086][ T4707] kmemleak: usb_gadget_register_driver_owner+0xf9/0x270
...
[ 79.308343][ T4707] kmemleak: unreferenced object 0xffff88814d973200 (size 192):
[ 79.308346][ T4707] kmemleak: comm "swapper/0", pid 1, jiffies 4294937600
[ 79.308348][ T4707] kmemleak: hex dump (first 32 bytes):
[ 79.308351][ T4707] kmemleak: 08 32 97 4d 81 88 ff ff 66 73 00 00 00 00 00 00 .2.M....fs......
[ 79.308353][ T4707] kmemleak: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................
[ 79.308355][ T4707] kmemleak: backtrace (crc 1443faf1):
[ 79.308357][ T4707] kmemleak: __kmalloc_cache_noprof+0x316/0x640
[ 79.308360][ T4707] kmemleak: uvcg_control_class_create_children+0x54/0x2e0
[ 79.308364][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308368][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308371][ T4707] kmemleak: uvcg_attach_configfs+0x33/0x60
[ 79.308375][ T4707] kmemleak: uvc_alloc_inst+0x6f9/0xa90
[ 79.308378][ T4707] kmemleak: usb_get_function_instance+0xe3/0x2f0
[ 79.308382][ T4707] kmemleak: webcam_bind+0x20/0x560
[ 79.308385][ T4707] kmemleak: composite_bind+0x1d2/0x530
[ 79.308388][ T4707] kmemleak: gadget_bind_driver+0x2ca/0x9e0
[ 79.308392][ T4707] kmemleak: really_probe+0x254/0xae0
[ 79.308395][ T4707] kmemleak: __driver_probe_device+0x1d9/0x350
[ 79.308398][ T4707] kmemleak: driver_probe_device+0x4f/0x240
[ 79.308401][ T4707] kmemleak: __driver_attach+0x339/0x600
[ 79.308404][ T4707] kmemleak: bus_for_each_dev+0x23b/0x2c0
[ 79.308408][ T4707] kmemleak: bus_add_driver+0x345/0x670
...
[ 79.308500][ T4707] kmemleak: unreferenced object 0xffff88814d972900 (size 192):
[ 79.308502][ T4707] kmemleak: comm "swapper/0", pid 1, jiffies 4294937600
[ 79.308504][ T4707] kmemleak: hex dump (first 32 bytes):
[ 79.308506][ T4707] kmemleak: 08 29 97 4d 81 88 ff ff 64 65 66 61 75 6c 74 00 .).M....default.
[ 79.308508][ T4707] kmemleak: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................
[ 79.308509][ T4707] kmemleak: backtrace (crc f01c5b6d):
[ 79.308511][ T4707] kmemleak: __kmalloc_cache_noprof+0x316/0x640
[ 79.308514][ T4707] kmemleak: uvcg_color_matching_create_children+0x53/0x2b0
[ 79.308518][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308521][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308525][ T4707] kmemleak: uvcg_attach_configfs+0x33/0x60
[ 79.308529][ T4707] kmemleak: uvc_alloc_inst+0x6f9/0xa90
[ 79.308532][ T4707] kmemleak: usb_get_function_instance+0xe3/0x2f0
[ 79.308536][ T4707] kmemleak: webcam_bind+0x20/0x560
[ 79.308539][ T4707] kmemleak: composite_bind+0x1d2/0x530
[ 79.308542][ T4707] kmemleak: gadget_bind_driver+0x2ca/0x9e0
[ 79.308546][ T4707] kmemleak: really_probe+0x254/0xae0
[ 79.308549][ T4707] kmemleak: __driver_probe_device+0x1d9/0x350
[ 79.308552][ T4707] kmemleak: driver_probe_device+0x4f/0x240
[ 79.308555][ T4707] kmemleak: __driver_attach+0x339/0x600
[ 79.308558][ T4707] kmemleak: bus_for_each_dev+0x23b/0x2c0
[ 79.308562][ T4707] kmemleak: bus_add_driver+0x345/0x670
...
[ 79.308732][ T4707] kmemleak: unreferenced object 0xffff88814d972500 (size 192):
[ 79.308734][ T4707] kmemleak: comm "swapper/0", pid 1, jiffies 4294937600
[ 79.308736][ T4707] kmemleak: hex dump (first 32 bytes):
[ 79.308738][ T4707] kmemleak: 08 25 97 4d 81 88 ff ff 73 73 00 00 00 00 00 00 .%.M....ss......
[ 79.308740][ T4707] kmemleak: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................
[ 79.308742][ T4707] kmemleak: backtrace (crc a8fa07b9):
[ 79.308743][ T4707] kmemleak: __kmalloc_cache_noprof+0x316/0x640
[ 79.308746][ T4707] kmemleak: uvcg_streaming_class_create_children+0x32f/0x470
[ 79.308750][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308754][ T4707] kmemleak: uvcg_config_create_children+0x20b/0x280
[ 79.308758][ T4707] kmemleak: uvcg_attach_configfs+0x33/0x60
[ 79.308761][ T4707] kmemleak: uvc_alloc_inst+0x6f9/0xa90
[ 79.308765][ T4707] kmemleak: usb_get_function_instance+0xe3/0x2f0
[ 79.308768][ T4707] kmemleak: webcam_bind+0x20/0x560
[ 79.308771][ T4707] kmemleak: composite_bind+0x1d2/0x530
[ 79.308775][ T4707] kmemleak: gadget_bind_driver+0x2ca/0x9e0
[ 79.308778][ T4707] kmemleak: really_probe+0x254/0xae0
[ 79.308781][ T4707] kmemleak: __driver_probe_device+0x1d9/0x350
[ 79.308784][ T4707] kmemleak: driver_probe_device+0x4f/0x240
[ 79.308787][ T4707] kmemleak: __driver_attach+0x339/0x600
[ 79.308790][ T4707] kmemleak: bus_for_each_dev+0x23b/0x2c0
[ 79.308794][ T4707] kmemleak: bus_add_driver+0x345/0x670
[ 79.308808][ T4707] kmemleak: 24 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
All of these configfs objects are created by uvcg_attach_configfs()
and rooted from 'func_inst.group' member of the corresponding
'struct f_uvc_opts' object. Not sure how it was expected to work
in 2014 (in particular, why uvc_func_item_release() should call
usb_put_function_instance() and who was responsible for doing
the matching call to usb_get_funcion_instance()), but fix all of
these leaks with config_group_put() called from uvc_free_inst().
Fixes: 46919a23ee87 ("usb: gadget: uvc: configfs support in uvc function")
Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
---
drivers/usb/gadget/function/f_uvc.c | 1 +
drivers/usb/gadget/function/uvc_configfs.c | 3 ---
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
index d1bf3ea75197..0783cab89ad8 100644
--- a/drivers/usb/gadget/function/f_uvc.c
+++ b/drivers/usb/gadget/function/f_uvc.c
@@ -908,6 +908,7 @@ static void uvc_free_inst(struct usb_function_instance *f)
{
struct f_uvc_opts *opts = fi_to_f_uvc_opts(f);
+ config_group_put(&opts->func_inst.group);
mutex_destroy(&opts->lock);
kfree(opts);
}
diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
index 70a1415ea401..5c44c7946351 100644
--- a/drivers/usb/gadget/function/uvc_configfs.c
+++ b/drivers/usb/gadget/function/uvc_configfs.c
@@ -3634,10 +3634,7 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
static void uvc_func_item_release(struct config_item *item)
{
- struct f_uvc_opts *opts = to_f_uvc_opts(item);
-
uvcg_config_remove_children(to_config_group(item));
- usb_put_function_instance(&opts->func_inst);
}
static int uvc_func_allow_link(struct config_item *src, struct config_item *tgt)
--
2.55.0
More information about the lvc-project
mailing list