usb: gadget: f_uac1_legacy: fix double close of the ALSA devices
PATCH 1/1 usb: gadget: f_uac1_legacy: fix double close of the ALSA devices
f_audio_bind() records that the ALSA files are open in the function instance flag opts->bound, but keeps the file pointers in the per-function gaudio card. Its error path calls gaudio_cleanup(), which closes the files without clearing the filp pointers or opts->bound. A failed bind does not destroy the usb_function, configfs_composite_bind() puts it back on cfg->func_list, so the next write to UDC binds the same f_audio, skips gaudio_setup() because opts->bound is still set, and on failure closes the files a second time. Dropping the config symlink after a failed bind closes them again via f_audio_free().
BUG: KASAN: slab-use-after-free in filp_flush+0x31/0x190 fs/open.c:1464 Read of size 8 at addr ffff888045f01990 by task syz-executor659/5617 Call Trace: filp_close+0x1d/0x40 fs/open.c:1484 gaudio_close_snd_dev drivers/usb/gadget/function/u_uac1_legacy.c:263 [inline] gaudio_cleanup+0x54/0xf0 drivers/usb/gadget/function/u_uac1_legacy.c:305 f_audio_bind+0x4a0/0x630 drivers/usb/gadget/function/f_uac1_legacy.c:792 usb_add_function+0x290/0x930 drivers/usb/gadget/composite.c:333 configfs_composite_bind+0xde0/0x1410 drivers/usb/gadget/configfs.c:1802 gadget_bind_driver+0x2ca/0x9e0 drivers/usb/gadget/udc/core.c:1662 gadget_dev_desc_UDC_store+0x1c9/0x2f0 drivers/usb/gadget/configfs.c:300
Clear filp, substream and card in gaudio_close_snd_dev() so cleanup is idempotent, and close the devices on the bind error path only if that bind opened them, resetting opts->bound as well.
--- drivers/usb/gadget/function/f_uac1_legacy.c | 8 +++++++- drivers/usb/gadget/function/u_uac1_legacy.c | 17 ++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_uac1_legacy.c +7 -1
@@ -732,6 +732,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)int status;struct usb_ep *ep =NULL ;struct f_uac1_legacy_opts *audio_opts; +bool bound_here = false; audio_opts = container_of(f->fi, struct f_uac1_legacy_opts, func_inst); audio->card.gadget = c->cdev->gadget;
@@ -741,6 +742,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)if (status <0 )return status; audio_opts->bound = true; + bound_here = true; } us =usb_gstrings_attach (cdev, uac1_strings,ARRAY_SIZE (strings_uac1));if (IS_ERR (us))
@@ -789,7 +791,11 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f)return 0 ; fail: -gaudio_cleanup (&audio->card); +/* Only tear down the ALSA devices if this bind opened them; the */ +if (bound_here) { +gaudio_cleanup (&audio->card); + audio_opts->bound = false; + }return status; }
drivers/usb/gadget/function/u_uac1_legacy.c +14 -3
@@ -259,18 +259,29 @@ static int gaudio_close_snd_dev(struct gaudio *gau)/* Close control device */ snd = &gau->control; -if (snd->filp) +if (snd->filp) {filp_close (snd->filp,NULL ); + snd->filp =NULL ; + snd->card =NULL ; + }/* Close PCM playback device and setup substream */ snd = &gau->playback; -if (snd->filp) +if (snd->filp) {filp_close (snd->filp,NULL ); + snd->filp =NULL ; + snd->substream =NULL ; + snd->card =NULL ; + }/* Close PCM capture device and setup substream */ snd = &gau->capture; -if (snd->filp) +if (snd->filp) {filp_close (snd->filp,NULL ); + snd->filp =NULL ; + snd->substream =NULL ; + snd->card =NULL ; + }return 0 ; }
---
base-commit: 8ba098e6b6ff0db8edf28528d1552be261af30d4
change-id: 20260731-alsa-656c9f27b141
Best regards,
Signature · 1 line
Vasileios Almpanis <[email protected]>
Quoted 22 lines
f_audio_bind()records that the ALSA files are open in the function instance flagopts->bound, but keeps the file pointers in the per-function gaudio card. Its error path callsgaudio_cleanup(), which closes the files without clearing the filp pointers oropts->bound. A failed bind does not destroy theusb_function,configfs_composite_bind()puts it back oncfg->func_list, so the next write to UDC binds the samef_audio, skipsgaudio_setup()becauseopts->boundis still set, and on failure closes the files a second time. Dropping the config symlink after a failed bind closes them again viaf_audio_free().BUG: KASAN: slab-use-after-free in filp_flush+0x31/0x190 fs/open.c:1464 Read of size 8 at addr ffff888045f01990 by task syz-executor659/5617 Call Trace: filp_close+0x1d/0x40 fs/open.c:1484 gaudio_close_snd_dev drivers/usb/gadget/function/u_uac1_legacy.c:263 [inline] gaudio_cleanup+0x54/0xf0 drivers/usb/gadget/function/u_uac1_legacy.c:305 f_audio_bind+0x4a0/0x630 drivers/usb/gadget/function/f_uac1_legacy.c:792 usb_add_function+0x290/0x930 drivers/usb/gadget/composite.c:333 configfs_composite_bind+0xde0/0x1410 drivers/usb/gadget/configfs.c:1802 gadget_bind_driver+0x2ca/0x9e0 drivers/usb/gadget/udc/core.c:1662 gadget_dev_desc_UDC_store+0x1c9/0x2f0 drivers/usb/gadget/configfs.c:300
Quoted 4 lines
Clear filp, substream and card in
gaudio_close_snd_dev()so cleanup is idempotent, and close the devices on the bind error path only if that bind opened them, resettingopts->boundas well.
Hi everyone,
Just following up on this patch. It has been already been tested with syzbot and the issue appears as fixed with this patch. Could you please take a look when you get a chance?
Kind regards,
Signature · 1 line
Vasileios Almpanis <[email protected]>