usb: gadget: f_eem: Fix memory leak in eem_unwrap

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: 4249d6fbc1 ("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>
This commit is contained in:
Kuen-Han Tsai 2025-11-03 20:17:59 +08:00 committed by Greg Kroah-Hartman
parent 46b28d2fbd
commit e4f5ce9908
1 changed files with 6 additions and 1 deletions

View File

@ -477,8 +477,13 @@ static int eem_unwrap(struct gether *port,
req->complete = eem_cmd_complete; req->complete = eem_cmd_complete;
req->zero = 1; req->zero = 1;
req->context = ctx; 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"); DBG(cdev, "echo response queue fail\n");
kfree(ctx);
kfree(req->buf);
usb_ep_free_request(ep, req);
dev_kfree_skb_any(skb2);
}
break; break;
case 1: /* echo response */ case 1: /* echo response */