[PATCH] usb: gadget: u_audio: size feedback buffer for 4-byte writes

From: Noah Weinberger

Date: Sun Nov 08 2026 - 18:57:30 EST


Hello,

u_audio_set_fback_frequency() stores the feedback value with an
unconditional 4-byte write:

*(__le32 *)buf = cpu_to_le32(ff);

but the feedback request buffer is allocated with the endpoint's
maxpacket size (u_audio.c: req_len = ep_fback->maxpacket; ...
kzalloc(req_len)),
and the full-speed feedback endpoint in f_uac2 (and f_uac1_legacy)
has wMaxPacketSize = 3. At full speed the store therefore writes one
byte past the allocation on every feedback completion. The FS shift
conversion just above already produces the correct 3-byte format -
only the store width is wrong.

The patch keeps the request length at maxpacket (3 bytes on the
wire) but sizes the buffer for the 4-byte store.

Affected version/commit: mainline 8a65162514fbad21a2c58ffed65f42b27e92b163 (v7.4-rc2 window, 2026-11-08), drivers/usb/gadget/function/u_audio.c:144-146 (u_audio_set_fback_frequency ends with an unconditional *(__le32 *)buf = cpu_to_le32(ff)), :653 and :665 (req_len = ep_fback->maxpacket; req_fback->buf = kzalloc(req_len)), f_uac2.c:383-391 (fs_epin_fback_desc wMaxPacketSize = 3 at full speed)
Longstanding since the shared u_audio feedback path was added.

This was found during an assisted (AI-supported) static source review of
mainline 8a65162514fbad21a2c58ffed65f42b27e92b163 (v7.4-rc2 window, 2026-11-08). 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.

---
diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c
index f0ee83abce..f7745131b0 100644
--- a/drivers/usb/gadget/function/u_audio.c
+++ b/drivers/usb/gadget/function/u_audio.c
@@ -662,7 +662,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
req_fback->length = req_len;
req_fback->complete = u_audio_iso_fback_complete;

- req_fback->buf = kzalloc(req_len, GFP_ATOMIC);
+ req_fback->buf = kzalloc(max_t(u32, req_len, 4), GFP_ATOMIC);
if (!req_fback->buf)
return -ENOMEM;