On Tue Jun 30 22:54:34 2026 +0800, Jiangong.Han wrote:
> When a device with has_dual_ts=1 is probed and the is_audio_only path
> is taken, both dev and dev->dev_next are added to the global
> em28xx_devlist via em28xx_init_extension(). However, during disconnect,
> em28xx_close_extension(dev) only calls list_del(&dev->devlist), leaving
> dev->dev_next->devlist still linked in the global list. When dev_next is
> subsequently freed via kref_put(), its devlist entry becomes a dangling
> pointer in em28xx_devlist. The next device probe that calls
> em28xx_init_extension() triggers a list corruption BUG when list_add_tail
> detects the freed node.
>
> This bug was exposed by commit a368ecde8a50 ("USB: core: Fix duplicate
> endpoint bug by clearing reserved bits in the descriptor") which clears
> reserved bits in bEndpointAddress during endpoint parsing. This causes
> fuzzed endpoint addresses like 0xf3 to be normalized to 0x83, which
> em28xx interprets as a vendor audio endpoint, enabling the
> is_audio_only + has_dual_ts code path that was previously unreachable
> with such descriptors.
>
> Fix this by removing dev->dev_next->devlist from the global list in
> em28xx_close_extension() before the device is freed.
>
> Fixes: f410b4093fdd ("media: em28xx: split up em28xx_dvb_init to reduce stack
> size")
> Cc: [email protected]
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=99d6c66dbbc484f50e1c
> Signed-off-by: Jiangong.Han <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/usb/em28xx/em28xx-core.c | 2 ++
1 file changed, 2 insertions(+)
---
diff --git a/drivers/media/usb/em28xx/em28xx-core.c
b/drivers/media/usb/em28xx/em28xx-core.c
index d4197e37f637..0b998e7cafef 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -1265,6 +1265,8 @@ void em28xx_close_extension(struct em28xx *dev)
ops->fini(dev);
}
}
+ if (dev->dev_next)
+ list_del(&dev->dev_next->devlist);
list_del(&dev->devlist);
mutex_unlock(&em28xx_devlist_mutex);
}
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]