From: sashiko-bot@kernel.org
To: "Xu Yang" <xu.yang_2@oss.nxp.com>
Cc: imx@lists.linux.dev, Frank.Li@kernel.org
Subject: Re: [PATCH] usb: gadget: f_uac1_legacy: remove broken string configfs attributes
Date: Mon, 13 Jul 2026 05:14:55 +0000 [thread overview]
Message-ID: <20260713051456.1C0421F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260713050246.3739137-1-xu.yang_2@oss.nxp.com>
Thank you for your contribution! Sashiko AI review found 11 potential issue(s) to consider:
New issues:
- [Low] The commit removes dynamic string configfs attributes but leaves deallocation logic and state tracking intact, resulting in dead code.
- [Low] The patch leaves stale references to the removed configfs attributes in user documentation.
Pre-existing issues:
- [Critical] Failure to allocate a new audio buffer in the completion handler leaves a dangling pointer in audio->copy_buf, leading to List Corruption and Use-After-Free.
- [Critical] Handling of alt == 0 fails to stop the endpoint or clear audio->copy_buf, leading to Use-After-Free and Double Free.
- [Critical] Failed buffer allocation assigns an error pointer to audio->copy_buf, which is later dereferenced as a valid pointer.
- [High] Missing cancel_work_sync() during gadget unbind leads to Use-After-Free in the playback workqueue.
- [High] Allocated usb_request objects and their buffers are never freed, causing a severe memory leak.
- [High] Unprotected list modification in f_audio_set_alt.
- [High] Premature hardirq enable in USB endpoint completion handler.
- [High] Missing queue drain loop in f_audio_playback_work causes unbounded list growth.
- [High] Unvalidated audio_buf_size and req_buf_size configfs parameters allow a heap buffer overflow.
--
--- Patch [1]: [PATCH] usb: gadget: f_uac1_legacy: remove broken string configfs attributes ---
commit 133e7d78a83d2788e14ca436593367567a36c8b9
Author: Xu Yang <xu.yang_2@nxp.com>
usb: gadget: f_uac1_legacy: remove broken string configfs attributes
The UAC1_STR_ATTRIBUTE macro defines configfs show/store handlers for
the fn_play, fn_cap, and fn_cntl string options. The attributes have been
broken and unused for many years, so remove them.
Link: https://lore.kernel.org/linux-usb/20260625113154.1954813-1-xu.yang_2@oss.nxp.com/
> diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
> index b2eaefd9bc498..6a681d219f439 100644
> --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
> +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
> @@ -5,8 +5,5 @@ Description:
> The attributes:
>
> audio_buf_size - audio buffer size
> - fn_cap - capture pcm device file name
> - fn_cntl - control device file name
> - fn_play - playback pcm device file name
[Severity: Low]
Does this patch leave stale references to the removed configfs attributes
in user documentation?
Documentation/usb/gadget-testing.rst:
...
fn_cap capture pcm device file name
fn_cntl control device file name
fn_play playback pcm device file name
...
> req_buf_size - ISO OUT endpoint request buffer size
> req_count - ISO OUT endpoint request count
> diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c
> index 5d201a2e30e7f..b15f5e074f856 100644
> --- a/drivers/usb/gadget/function/f_uac1_legacy.c
> +++ b/drivers/usb/gadget/function/f_uac1_legacy.c
> @@ -888,60 +888,10 @@ UAC1_INT_ATTRIBUTE(req_buf_size);
> UAC1_INT_ATTRIBUTE(req_count);
> UAC1_INT_ATTRIBUTE(audio_buf_size);
>
> -#define UAC1_STR_ATTRIBUTE(name) \
[ ... ]
> -UAC1_STR_ATTRIBUTE(fn_play);
> -UAC1_STR_ATTRIBUTE(fn_cap);
> -UAC1_STR_ATTRIBUTE(fn_cntl);
[Severity: Low]
With these attributes removed, does this leave dead code blocks in
f_audio_free_inst() that check the now-always-false allocation flags?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_free_inst() {
...
opts = container_of(f, struct f_uac1_legacy_opts, func_inst);
if (opts->fn_play_alloc)
kfree(opts->fn_play);
if (opts->fn_cap_alloc)
kfree(opts->fn_cap);
if (opts->fn_cntl_alloc)
kfree(opts->fn_cntl);
...
}
And does it also leave permanently unused bitfields in
struct f_uac1_legacy_opts?
drivers/usb/gadget/function/u_uac1_legacy.h:struct f_uac1_legacy_opts {
...
unsigned fn_play_alloc:1;
unsigned fn_cap_alloc:1;
unsigned fn_cntl_alloc:1;
...
}
> static struct configfs_attribute *f_uac1_attrs[] = {
> &f_uac1_opts_attr_req_buf_size,
[ ... ]
[Severity: High]
This is a pre-existing issue, but does f_audio_free() lead to a use-after-free
if the playback workqueue executes on the freed memory?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_free() {
...
kfree(audio);
mutex_lock(&opts->lock);
...
}
It appears the structure is freed without cancelling the playback_work.
[Severity: High]
This is a pre-existing issue, but are the allocated usb_request objects and
their buffers never freed?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_set_alt() {
...
req = usb_ep_alloc_request(out_ep, GFP_ATOMIC);
if (req) {
req->buf = kzalloc(req_buf_size,
GFP_ATOMIC);
...
}
Every set_alt(1) from the host allocates a batch of requests and buffers, but
usb_ep_free_request() doesn't seem to be called anywhere in the driver.
[Severity: Critical]
This is a pre-existing issue, but does a failure to allocate a new audio buffer
leave a dangling pointer in audio->copy_buf?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_out_ep_complete() {
...
copy_buf = f_audio_buffer_alloc(audio_buf_size);
if (IS_ERR(copy_buf))
return -ENOMEM;
...
}
Returning early here leaves audio->copy_buf pointing to the buffer that was
just queued for playback or freed, potentially leading to list corruption and
a use-after-free.
[Severity: Critical]
This is a pre-existing issue, but does the handling of alt == 0 fail to stop
the endpoint or clear audio->copy_buf?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_set_alt() {
...
} else {
struct f_audio_buf *copy_buf = audio->copy_buf;
if (copy_buf) {
list_add_tail(©_buf->list,
&audio->play_queue);
schedule_work(&audio->playback_work);
}
}
...
}
Because usb_ep_disable() is not called, can the endpoint continue receiving
data into copy_buf which was just queued to play_queue?
[Severity: Critical]
This is a pre-existing issue, but can a failed buffer allocation assign an
error pointer to audio->copy_buf, which is later dereferenced?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_set_alt() {
...
audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
if (IS_ERR(audio->copy_buf))
return -ENOMEM;
...
}
If a subsequent set_alt(0) is received:
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_set_alt() {
...
if (copy_buf) {
list_add_tail(©_buf->list,
&audio->play_queue);
...
}
ERR_PTR(-ENOMEM) evaluates as true, which would cause list_add_tail() to
write to an invalid pointer offset.
[Severity: High]
This is a pre-existing issue, but is this list modification unprotected?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_set_alt() {
...
list_add_tail(©_buf->list,
&audio->play_queue);
...
}
It accesses and modifies audio->play_queue without holding audio->lock, which
could race concurrently with f_audio_playback_work() and completion handlers.
[Severity: High]
This is a pre-existing issue, but does this prematurely enable hardirqs
inside a USB completion callback?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_out_ep_complete() {
...
spin_unlock_irq(&audio->lock);
...
}
Calling spin_unlock_irq() unconditionally unmasks hardware interrupts,
which violates IRQ masking state if the callback natively runs in interrupt
context.
[Severity: High]
This is a pre-existing issue, but does the lack of a queue drain loop in
f_audio_playback_work() cause unbounded list growth?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_playback_work() {
...
play_buf = list_first_entry(&audio->play_queue,
struct f_audio_buf, list);
list_del(&play_buf->list);
spin_unlock_irq(&audio->lock);
u_audio_playback(&audio->card, play_buf->buf, play_buf->actual);
f_audio_buffer_free(play_buf);
...
}
Since schedule_work() coalesces, if multiple audio packets complete before
the scheduled work executes, this will pop only one item and permanently
delay the processing of accumulated concurrent items.
[Severity: High]
This is a pre-existing issue, but can unvalidated audio_buf_size and
req_buf_size parameters allow a heap buffer overflow?
drivers/usb/gadget/function/f_uac1_legacy.c:f_audio_out_ep_complete() {
...
memcpy(copy_buf->buf + copy_buf->actual, req->buf, req->actual);
...
}
If a user configures the gadget with req_buf_size larger than audio_buf_size,
the length of data copied (req->actual) could overflow the newly allocated
copy_buf->buf.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260713050246.3739137-1-xu.yang_2@oss.nxp.com?part=1
next prev parent reply other threads:[~2026-07-13 5:14 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-13 5:02 [PATCH] usb: gadget: f_uac1_legacy: remove broken string configfs attributes Xu Yang
2026-07-13 5:14 ` sashiko-bot [this message]
2026-07-13 14:45 ` Frank Li
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=20260713051456.1C0421F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=imx@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=xu.yang_2@oss.nxp.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