mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Christophe JAILLET <christophe.jaillet@wanadoo.fr>,
	Kees Cook <kees@kernel.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	syzbot+28cf08dec5895bd562e6@syzkaller.appspotmail.com,
	Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
Subject: [PATCH v2] usb: gadget: f_loopback: fix descriptor leak on unbind
Date: Tue, 15 Sep 2026 08:44:17 +0000	[thread overview]
Message-ID: <20260915084417.131614-1-nagachaithanya9911@gmail.com> (raw)
In-Reply-To: <20260808181504.462492-1-nagachaithanya9911@gmail.com>

loopback_bind() allocates descriptor copies through
usb_assign_descriptors(), but f_loopback does not release them during
the unbind path. On every bind/unbind cycle of the gadget (for example
by repeatedly writing the UDC attribute through configfs) a new set of
descriptors is allocated while the previous ones are leaked. syzbot
reported this via kmemleak:

  BUG: memory leak
  unreferenced object 0xffff888016b8f180 (size 64):
    comm "repro", pid 5613
    backtrace:
      __kmalloc_noprof+0x3bf/0x550
      usb_copy_descriptors+0x6c/0x160
      usb_assign_descriptors+0x48/0x180
      loopback_bind+0xff/0x120
      usb_add_function+0xca/0x270
      configfs_composite_bind+0x667/0x9b0
      gadget_bind_driver+0xed/0x390

Move descriptor cleanup to a new loopback_unbind() callback that frees
them with usb_free_all_descriptors(), matching the lifecycle used by
other gadget functions such as f_acm. With descriptors released during
unbind, the usb_free_all_descriptors() call in lb_free_func() becomes
redundant and can be removed.

Tested with CONFIG_DEBUG_KMEMLEAK=y, CONFIG_USB_CONFIGFS_F_LB_SS=y and
CONFIG_USBIP_VUDC=y by running the syzbot reproducer in QEMU with
kmemleak=on. The patched and unpatched kernels were built from the same
tree, config and compiler, so this patch is the only difference between
them. Without it, five reproducer iterations produce three leak reports,
every one of them through loopback_bind(). With it applied, 25
iterations produce none and kmemleak stays silent.

Fixes: 10287baec761 ("usb: gadget: always update HS/SS descriptors and create a copy of them")
Reported-by: syzbot+28cf08dec5895bd562e6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=28cf08dec5895bd562e6
Tested-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
---
v2:
 - Add the Assisted-by: tag that should have been in v1 (Greg KH).
 - Describe the kmemleak testing in the commit message (Greg KH).
 - No change to the code; the diff is identical to v1.

Link to v1:
https://lore.kernel.org/all/20260808181504.462492-1-nagachaithanya9911@gmail.com/

 drivers/usb/gadget/function/f_loopback.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c
index d2d07fb49e70..40aaf2eb00f2 100644
--- a/drivers/usb/gadget/function/f_loopback.c
+++ b/drivers/usb/gadget/function/f_loopback.c
@@ -216,6 +216,11 @@ static int loopback_bind(struct usb_configuration *c, struct usb_function *f)
 	return 0;
 }
 
+static void loopback_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+	usb_free_all_descriptors(f);
+}
+
 static void lb_free_func(struct usb_function *f)
 {
 	struct f_lb_opts *opts;
@@ -226,7 +231,6 @@ static void lb_free_func(struct usb_function *f)
 	opts->refcnt--;
 	mutex_unlock(&opts->lock);
 
-	usb_free_all_descriptors(f);
 	kfree(func_to_loop(f));
 }
 
@@ -442,6 +446,7 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
 
 	loop->function.name = "loopback";
 	loop->function.bind = loopback_bind;
+	loop->function.unbind = loopback_unbind;
 	loop->function.set_alt = loopback_set_alt;
 	loop->function.disable = loopback_disable;
 	loop->function.strings = loopback_strings;
-- 
2.43.0


      parent reply	other threads:[~2026-09-15  8:44 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-08 18:15 [PATCH] " Chaithanya Lagisetty
     [not found] ` <CALFZYQUzfbVnAhSqR6JmfDB-zvuiGSWx+9tCBc03xfBxJS9h0Q@mail.gmail.com>
2026-08-23 16:56   ` Greg Kroah-Hartman
2026-09-02 10:51 ` [PATCH RESEND] " Chaithanya Lagisetty
2026-09-10 16:32   ` Greg KH
2026-09-11  9:01     ` Chaithanya Lagisetty
2026-09-15  8:44 ` Chaithanya Lagisetty [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260915084417.131614-1-nagachaithanya9911@gmail.com \
    --to=nagachaithanya9911@gmail.com \
    --cc=bigeasy@linutronix.de \
    --cc=christophe.jaillet@wanadoo.fr \
    --cc=gregkh@linuxfoundation.org \
    --cc=kees@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=syzbot+28cf08dec5895bd562e6@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®