CVE-2021-47634

Severity CVSS v4.0:
Pending analysis
Type:
CWE-416 Use After Free
Publication date:
26/02/2025
Last modified:
24/03/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl<br /> <br /> Hulk Robot reported a KASAN report about use-after-free:<br /> ==================================================================<br /> BUG: KASAN: use-after-free in __list_del_entry_valid+0x13d/0x160<br /> Read of size 8 at addr ffff888035e37d98 by task ubiattach/1385<br /> [...]<br /> Call Trace:<br /> klist_dec_and_del+0xa7/0x4a0<br /> klist_put+0xc7/0x1a0<br /> device_del+0x4d4/0xed0<br /> cdev_device_del+0x1a/0x80<br /> ubi_attach_mtd_dev+0x2951/0x34b0 [ubi]<br /> ctrl_cdev_ioctl+0x286/0x2f0 [ubi]<br /> <br /> Allocated by task 1414:<br /> device_add+0x60a/0x18b0<br /> cdev_device_add+0x103/0x170<br /> ubi_create_volume+0x1118/0x1a10 [ubi]<br /> ubi_cdev_ioctl+0xb7f/0x1ba0 [ubi]<br /> <br /> Freed by task 1385:<br /> cdev_device_del+0x1a/0x80<br /> ubi_remove_volume+0x438/0x6c0 [ubi]<br /> ubi_cdev_ioctl+0xbf4/0x1ba0 [ubi]<br /> [...]<br /> ==================================================================<br /> <br /> The lock held by ctrl_cdev_ioctl is ubi_devices_mutex, but the lock held<br /> by ubi_cdev_ioctl is ubi-&gt;device_mutex. Therefore, the two locks can be<br /> concurrent.<br /> <br /> ctrl_cdev_ioctl contains two operations: ubi_attach and ubi_detach.<br /> ubi_detach is bug-free because it uses reference counting to prevent<br /> concurrency. However, uif_init and uif_close in ubi_attach may race with<br /> ubi_cdev_ioctl.<br /> <br /> uif_init will race with ubi_cdev_ioctl as in the following stack.<br /> cpu1 cpu2 cpu3<br /> _______________________|________________________|______________________<br /> ctrl_cdev_ioctl<br /> ubi_attach_mtd_dev<br /> uif_init<br /> ubi_cdev_ioctl<br /> ubi_create_volume<br /> cdev_device_add<br /> ubi_add_volume<br /> // sysfs exist<br /> kill_volumes<br /> ubi_cdev_ioctl<br /> ubi_remove_volume<br /> cdev_device_del<br /> // first free<br /> ubi_free_volume<br /> cdev_del<br /> // double free<br /> cdev_device_del<br /> <br /> And uif_close will race with ubi_cdev_ioctl as in the following stack.<br /> cpu1 cpu2 cpu3<br /> _______________________|________________________|______________________<br /> ctrl_cdev_ioctl<br /> ubi_attach_mtd_dev<br /> uif_init<br /> ubi_cdev_ioctl<br /> ubi_create_volume<br /> cdev_device_add<br /> ubi_debugfs_init_dev<br /> //error goto out_uif;<br /> uif_close<br /> kill_volumes<br /> ubi_cdev_ioctl<br /> ubi_remove_volume<br /> cdev_device_del<br /> // first free<br /> ubi_free_volume<br /> // double free<br /> <br /> The cause of this problem is that commit 714fb87e8bc0 make device<br /> "available" before it becomes accessible via sysfs. Therefore, we<br /> roll back the modification. We will fix the race condition between<br /> ubi device creation and udev by removing ubi_get_device in<br /> vol_attribute_show and dev_attribute_show.This avoids accessing<br /> uninitialized ubi_devices[ubi_num].<br /> <br /> ubi_get_device is used to prevent devices from being deleted during<br /> sysfs execution. However, now kernfs ensures that devices will not<br /> be deleted before all reference counting are released.<br /> The key process is shown in the following stack.<br /> <br /> device_del<br /> device_remove_attrs<br /> device_remove_groups<br /> sysfs_remove_groups<br /> sysfs_remove_group<br /> remove_files<br /> kernfs_remove_by_name<br /> kernfs_remove_by_name_ns<br /> __kernfs_remove<br /> kernfs_drain

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.2.84 (including) 3.3 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.10.103 (including) 3.11 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.12.63 (including) 3.13 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.14.77 (including) 3.15 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.16.39 (including) 3.17 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 3.18.40 (including) 3.19 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.1.31 (including) 4.2 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.4.19 (including) 4.5 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.7.2 (including) 4.14.276 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.15 (including) 4.19.238 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.20 (including) 5.4.189 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.5 (including) 5.10.110 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (including) 5.15.33 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 5.16.19 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.17 (including) 5.17.2 (excluding)