[PATCH] usb: gadget: f_hid: free report list on release
From: Noah Weinberger
Date: Sun Nov 08 2026 - 17:33:40 EST
Hello,
Entries added to hidg->report_list by the GADGET_HID_WRITE_GET_REPORT
ioctl are never freed: hidg_release() releases report_desc,
set_report_buf and hidg itself, but never walks the list (and
hidg_unbind() does not either). Each distinct report_id used over the
lifetime of a function instance therefore leaks one entry (~72 bytes),
which adds up across gadget reconfiguration cycles.
Free the list when the device's last reference is dropped.
Affected version/commit: mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07), drivers/usb/gadget/function/f_hid.c:679-682 (list add), 121-128 (hidg_release).
The report-list mechanism is newer; the leak is present at HEAD.
This was found during an assisted (AI-supported) static source review of
mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07); every code path cited below was re-verified by the
reporter against that tree. The patch below has NOT been compiled and has
NOT been runtime tested, and no reproducer was produced - the triggering
conditions are described above instead. Please treat this as a report for
verification rather than a battle-tested fix.
Reported-by: Noah Weinberger <noahweinberger2003@xxxxxxxxx>
---
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index 3c6b43d..dcf6dce 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -121,6 +121,13 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f)
static void hidg_release(struct device *dev)
{
struct f_hidg *hidg = container_of(dev, struct f_hidg, dev);
+ struct report_entry *entry, *tmp;
+
+ list_for_each_entry_safe(entry, tmp, &hidg->report_list, node) {
+ list_del(&entry->node);
+ kfree(entry);
+ }
+
kfree(hidg->report_desc);
kfree(hidg->set_report_buf);