]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
usb: gadget: f_eem: Fix memory leak in eem_unwrap
authorKuen-Han Tsai <khtsai@google.com>
Mon, 3 Nov 2025 12:17:59 +0000 (20:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Nov 2025 02:11:19 +0000 (11:11 +0900)
The existing code did not handle the failure case of usb_ep_queue in the
command path, potentially leading to memory leaks.

Improve error handling to free all allocated resources on usb_ep_queue
failure. This patch continues to use goto logic for error handling, as the
existing error handling is complex and not easily adaptable to auto-cleanup
helpers.

kmemleak results:
  unreferenced object 0xffffff895a512300 (size 240):
    backtrace:
      slab_post_alloc_hook+0xbc/0x3a4
      kmem_cache_alloc+0x1b4/0x358
      skb_clone+0x90/0xd8
      eem_unwrap+0x1cc/0x36c
  unreferenced object 0xffffff8a157f4000 (size 256):
    backtrace:
      slab_post_alloc_hook+0xbc/0x3a4
      __kmem_cache_alloc_node+0x1b4/0x2dc
      kmalloc_trace+0x48/0x140
      dwc3_gadget_ep_alloc_request+0x58/0x11c
      usb_ep_alloc_request+0x40/0xe4
      eem_unwrap+0x204/0x36c
  unreferenced object 0xffffff8aadbaac00 (size 128):
    backtrace:
      slab_post_alloc_hook+0xbc/0x3a4
      __kmem_cache_alloc_node+0x1b4/0x2dc
      __kmalloc+0x64/0x1a8
      eem_unwrap+0x218/0x36c
  unreferenced object 0xffffff89ccef3500 (size 64):
    backtrace:
      slab_post_alloc_hook+0xbc/0x3a4
      __kmem_cache_alloc_node+0x1b4/0x2dc
      kmalloc_trace+0x48/0x140
      eem_unwrap+0x238/0x36c

Fixes: 4249d6fbc10f ("usb: gadget: eem: fix echo command packet response issue")
Cc: stable@kernel.org
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
Link: https://patch.msgid.link/20251103121814.1559719-1-khtsai@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/f_eem.c

index 6de81ea1727432601873966942e49f6c0ec16c90..edbbadad613815cdd968a647deba6b26dd12b2c1 100644 (file)
@@ -477,8 +477,13 @@ static int eem_unwrap(struct gether *port,
                                req->complete = eem_cmd_complete;
                                req->zero = 1;
                                req->context = ctx;
-                               if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC))
+                               if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) {
                                        DBG(cdev, "echo response queue fail\n");
+                                       kfree(ctx);
+                                       kfree(req->buf);
+                                       usb_ep_free_request(ep, req);
+                                       dev_kfree_skb_any(skb2);
+                               }
                                break;
 
                        case 1:  /* echo response */