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->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
Impact
Base Score 3.x
7.80
Severity 3.x
HIGH
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) |
To consult the complete list of CPE names with products and versions, see this page
References to Advisories, Solutions, and Tools
- https://git.kernel.org/stable/c/1a3f1cf87054833242fcd0218de0481cf855f888
- https://git.kernel.org/stable/c/3cbf0e392f173ba0ce425968c8374a6aa3e90f2e
- https://git.kernel.org/stable/c/432b057f8e847ae5a2306515606f8d2defaca178
- https://git.kernel.org/stable/c/5f9e9c223e48c264241d2f34d0bfc29e5fcb5c1b
- https://git.kernel.org/stable/c/a8ecee49259f8f78d91ddb329ab2be7e6fd01974
- https://git.kernel.org/stable/c/c32fe764191b8ae8b128588beb96e3718d9179d8
- https://git.kernel.org/stable/c/d727fd32cbd1abf3465f607021bc9c746f17b5a8
- https://git.kernel.org/stable/c/f149b1bd213820363731aa119e5011ca892a2aac



