Re: [syzbot] [media?] KASAN: use-after-free Read in em28xx_close_extension (2)

From: Hillf Danton
Date: Fri Sep 20 2024 - 19:01:10 EST


On Thu, 19 Sep 2024 08:00:19 -0700
> syzbot found the following issue on:
>
> HEAD commit: 68d4209158f4 sub: cdns3: Use predefined PCI vendor ID cons..
> git tree: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=11166200580000

#syz test

--- x/drivers/media/usb/em28xx/em28xx-core.c
+++ y/drivers/media/usb/em28xx/em28xx-core.c
@@ -1134,7 +1134,7 @@ void em28xx_close_extension(struct em28x
ops->fini(dev);
}
}
- list_del(&dev->devlist);
+ list_del_init(&dev->devlist);
mutex_unlock(&em28xx_devlist_mutex);
}

--- x/drivers/media/usb/em28xx/em28xx-cards.c
+++ y/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3735,6 +3735,7 @@ static int em28xx_duplicate_dev(struct e
dev->dev_next = NULL;
return -ENOMEM;
}
+ INIT_LIST_HEAD(&sec_dev->devlist);
/* Check to see next free device and mark as used */
do {
nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
@@ -3910,6 +3911,7 @@ static int em28xx_usb_probe(struct usb_i
retval = -ENOMEM;
goto err;
}
+ INIT_LIST_HEAD(&dev->devlist);

/* compute alternate max packet sizes */
dev->alt_max_pkt_size_isoc = kcalloc(intf->num_altsetting,
@@ -4156,6 +4158,8 @@ static int em28xx_usb_probe(struct usb_i
return 0;

err_free:
+ if (!list_empty(&dev->devlist))
+ em28xx_close_extension(dev);
kfree(dev->alt_max_pkt_size_isoc);
kfree(dev);

@@ -4201,6 +4205,8 @@ static void em28xx_usb_disconnect(struct
em28xx_release_resources(dev);

if (dev->dev_next) {
+ if (!list_empty(&dev->dev_next->devlist))
+ em28xx_close_extension(dev->dev_next);
kref_put(&dev->dev_next->ref, em28xx_free_device);
dev->dev_next = NULL;
}
--