On Mon Sep 28 20:19:04 2026 -0400, Kaho Jiang wrote:
> When allocation of usb_bufs->buf[i] fails, em28xx_alloc_urbs()
> explicitly frees all items within usb_bufs->buf before calling
> em28xx_uninit_usb_xfer(), which also frees these items, causing them to be
> freed twice.
> 
> BUG: KASAN: double-free in usb_free_urb.part.0 (drivers/usb/core/urb.c:25 
> ./include/linux/kref.h:65 drivers/usb/core/urb.c:96)
> Free of addr ffff88802fd37c00 by task kworker/1:2/1182
> Workqueue: events request_module_async
> Call Trace:
>   kasan_report_invalid_free (mm/kasan/report.c:557)
>   check_slab_allocation (mm/kasan/common.c:235)
>   kfree (./include/linux/kasan.h:199 (discriminator 1) mm/slub.c:2693 
> (discriminator 1) mm/slub.c:6508 (discriminator 1) mm/slub.c:6801 
> (discriminator 1))
>   usb_free_urb.part.0 (drivers/usb/core/urb.c:25 ./include/linux/kref.h:65 
> drivers/usb/core/urb.c:96)
>   usb_free_urb (drivers/usb/core/urb.c:95)
>   em28xx_uninit_usb_xfer (drivers/media/usb/em28xx/em28xx-core.c:964)
>   em28xx_alloc_urbs (drivers/media/usb/em28xx/em28xx-core.c:1076)
>   em28xx_dvb_init (drivers/media/usb/em28xx/em28xx-dvb.c:1734 
> drivers/media/usb/em28xx/em28xx-dvb.c:1698)
>   em28xx_init_extension (drivers/media/usb/em28xx/em28xx-core.c:1248)
>   request_module_async (drivers/media/usb/em28xx/em28xx-cards.c:3685)
>   process_one_work (kernel/workqueue.c:3396)
>   worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
>   kthread (kernel/kthread.c:436)
>   ret_from_fork (arch/x86/kernel/process.c:158)
>   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
>   Allocated by task 1182:
>   kasan_save_stack (mm/kasan/common.c:57)
>   kasan_save_track (mm/kasan/common.c:78)
>   __kasan_kmalloc (mm/kasan/common.c:398 mm/kasan/common.c:415)
>   __kmalloc_noprof (./include/linux/kasan.h:263 mm/slub.c:5414 mm/slub.c:5439)
>   em28xx_alloc_urbs (./include/linux/slab.h:995 ./include/linux/slab.h:1312 
> drivers/media/usb/em28xx/em28xx-core.c:1081)
>   em28xx_dvb_init (drivers/media/usb/em28xx/em28xx-dvb.c:1734 
> drivers/media/usb/em28xx/em28xx-dvb.c:1698)
>   em28xx_init_extension (drivers/media/usb/em28xx/em28xx-core.c:1248)
>   request_module_async (drivers/media/usb/em28xx/em28xx-cards.c:3685)
>   process_one_work (kernel/workqueue.c:3396)
>   worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
>   kthread (kernel/kthread.c:436)
>   ret_from_fork (arch/x86/kernel/process.c:158)
>   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
>   Freed by task 1182:
>   kasan_save_stack (mm/kasan/common.c:57)
>   kasan_save_track (mm/kasan/common.c:78)
>   kasan_save_free_info (mm/kasan/generic.c:584)
>   __kasan_slab_free (mm/kasan/common.c:253 mm/kasan/common.c:285)
>   kfree (./include/linux/kasan.h:235 mm/slub.c:2748 mm/slub.c:6508 
> mm/slub.c:6801)
>   em28xx_alloc_urbs (drivers/media/usb/em28xx/em28xx-core.c:1084)
>   em28xx_dvb_init (drivers/media/usb/em28xx/em28xx-dvb.c:1734 
> drivers/media/usb/em28xx/em28xx-dvb.c:1698)
>   em28xx_init_extension (drivers/media/usb/em28xx/em28xx-core.c:1248)
>   request_module_async (drivers/media/usb/em28xx/em28xx-cards.c:3685)
>   process_one_work (kernel/workqueue.c:3396)
>   worker_thread (kernel/workqueue.c:3479 kernel/workqueue.c:3560)
>   kthread (kernel/kthread.c:436)
>   ret_from_fork (arch/x86/kernel/process.c:158)
>   ret_from_fork_asm (arch/x86/entry/entry_64.S:245)
> 
> Remove the explicit cleanup loop and let em28xx_uninit_usb_xfer()
> handle the cleanup.
> 
> Fixes: d571b592c6206 ("media: em28xx: don't use coherent buffer for DMA 
> transfers")
> Cc: [email protected]
> Reported-by: [email protected]
> Assisted-by: LLM
> Signed-off-by: Kaho Jiang <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/usb/em28xx/em28xx-core.c | 3 ---
 1 file changed, 3 deletions(-)

---

diff --git a/drivers/media/usb/em28xx/em28xx-core.c 
b/drivers/media/usb/em28xx/em28xx-core.c
index 0b998e7cafef..62a1c25a2de1 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -1080,9 +1080,6 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum 
em28xx_mode mode, int xfer_bulk,
 
                usb_bufs->buf[i] = kzalloc(sb_size, GFP_KERNEL);
                if (!usb_bufs->buf[i]) {
-                       for (i--; i >= 0; i--)
-                               kfree(usb_bufs->buf[i]);
-
                        em28xx_uninit_usb_xfer(dev, mode);
                        return -ENOMEM;
                }
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to