CVE-2024-53171
Severity CVSS v4.0:
Pending analysis
Type:
CWE-416
Use After Free
Publication date:
27/12/2024
Last modified:
03/11/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit<br />
<br />
After an insertion in TNC, the tree might split and cause a node to<br />
change its `znode->parent`. A further deletion of other nodes in the<br />
tree (which also could free the nodes), the aforementioned node&#39;s<br />
`znode->cparent` could still point to a freed node. This<br />
`znode->cparent` may not be updated when getting nodes to commit in<br />
`ubifs_tnc_start_commit()`. This could then trigger a use-after-free<br />
when accessing the `znode->cparent` in `write_index()` in<br />
`ubifs_tnc_end_commit()`.<br />
<br />
This can be triggered by running<br />
<br />
rm -f /etc/test-file.bin<br />
dd if=/dev/urandom of=/etc/test-file.bin bs=1M count=60 conv=fsync<br />
<br />
in a loop, and with `CONFIG_UBIFS_FS_AUTHENTICATION`. KASAN then<br />
reports:<br />
<br />
BUG: KASAN: use-after-free in ubifs_tnc_end_commit+0xa5c/0x1950<br />
Write of size 32 at addr ffffff800a3af86c by task ubifs_bgt0_20/153<br />
<br />
Call trace:<br />
dump_backtrace+0x0/0x340<br />
show_stack+0x18/0x24<br />
dump_stack_lvl+0x9c/0xbc<br />
print_address_description.constprop.0+0x74/0x2b0<br />
kasan_report+0x1d8/0x1f0<br />
kasan_check_range+0xf8/0x1a0<br />
memcpy+0x84/0xf4<br />
ubifs_tnc_end_commit+0xa5c/0x1950<br />
do_commit+0x4e0/0x1340<br />
ubifs_bg_thread+0x234/0x2e0<br />
kthread+0x36c/0x410<br />
ret_from_fork+0x10/0x20<br />
<br />
Allocated by task 401:<br />
kasan_save_stack+0x38/0x70<br />
__kasan_kmalloc+0x8c/0xd0<br />
__kmalloc+0x34c/0x5bc<br />
tnc_insert+0x140/0x16a4<br />
ubifs_tnc_add+0x370/0x52c<br />
ubifs_jnl_write_data+0x5d8/0x870<br />
do_writepage+0x36c/0x510<br />
ubifs_writepage+0x190/0x4dc<br />
__writepage+0x58/0x154<br />
write_cache_pages+0x394/0x830<br />
do_writepages+0x1f0/0x5b0<br />
filemap_fdatawrite_wbc+0x170/0x25c<br />
file_write_and_wait_range+0x140/0x190<br />
ubifs_fsync+0xe8/0x290<br />
vfs_fsync_range+0xc0/0x1e4<br />
do_fsync+0x40/0x90<br />
__arm64_sys_fsync+0x34/0x50<br />
invoke_syscall.constprop.0+0xa8/0x260<br />
do_el0_svc+0xc8/0x1f0<br />
el0_svc+0x34/0x70<br />
el0t_64_sync_handler+0x108/0x114<br />
el0t_64_sync+0x1a4/0x1a8<br />
<br />
Freed by task 403:<br />
kasan_save_stack+0x38/0x70<br />
kasan_set_track+0x28/0x40<br />
kasan_set_free_info+0x28/0x4c<br />
__kasan_slab_free+0xd4/0x13c<br />
kfree+0xc4/0x3a0<br />
tnc_delete+0x3f4/0xe40<br />
ubifs_tnc_remove_range+0x368/0x73c<br />
ubifs_tnc_remove_ino+0x29c/0x2e0<br />
ubifs_jnl_delete_inode+0x150/0x260<br />
ubifs_evict_inode+0x1d4/0x2e4<br />
evict+0x1c8/0x450<br />
iput+0x2a0/0x3c4<br />
do_unlinkat+0x2cc/0x490<br />
__arm64_sys_unlinkat+0x90/0x100<br />
invoke_syscall.constprop.0+0xa8/0x260<br />
do_el0_svc+0xc8/0x1f0<br />
el0_svc+0x34/0x70<br />
el0t_64_sync_handler+0x108/0x114<br />
el0t_64_sync+0x1a4/0x1a8<br />
<br />
The offending `memcpy()` in `ubifs_copy_hash()` has a use-after-free<br />
when a node becomes root in TNC but still has a `cparent` to an already<br />
freed node. More specifically, consider the following TNC:<br />
<br />
zroot<br />
/<br />
/<br />
zp1<br />
/<br />
/<br />
zn<br />
<br />
Inserting a new node `zn_new` with a key smaller then `zn` will trigger<br />
a split in `tnc_insert()` if `zp1` is full:<br />
<br />
zroot<br />
/ \<br />
/ \<br />
zp1 zp2<br />
/ \<br />
/ \<br />
zn_new zn<br />
<br />
`zn->parent` has now been moved to `zp2`, *but* `zn->cparent` still<br />
points to `zp1`.<br />
<br />
Now, consider a removal of all the nodes _except_ `zn`. Just when<br />
`tnc_delete()` is about to delete `zroot` and `zp2`:<br />
<br />
zroot<br />
\<br />
\<br />
zp2<br />
\<br />
\<br />
zn<br />
<br />
`zroot` and `zp2` get freed and the tree collapses:<br />
<br />
zn<br />
<br />
`zn` now becomes the new `zroot`.<br />
<br />
`get_znodes_to_commit()` will now only find `zn`, the new `zroot`, and<br />
`write_index()` will check its `znode->cparent` that wrongly points to<br />
the already freed `zp1`. `ubifs_copy_hash()` thus gets wrongly called<br />
with `znode->cparent->zbranch[znode->iip].hash` that triggers the<br />
use-after-free!<br />
<br />
Fix this by explicitly setting `znode->cparent` to `NULL` in<br />
`get_znodes_to_commit()` for the root node. The search for the dirty<br />
nodes<br />
---truncated---
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:*:*:*:*:*:*:*:* | 4.20 (including) | 5.4.287 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.5 (including) | 5.10.231 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.11 (including) | 5.15.174 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 5.16 (including) | 6.1.120 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.2 (including) | 6.6.64 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.7 (including) | 6.11.11 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.12 (including) | 6.12.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/01d3a2293d7e4edfff96618c15727db7e51f11b6
- https://git.kernel.org/stable/c/2497479aecebe869d23a0064e0fd1a03e34f0e2a
- https://git.kernel.org/stable/c/398a91599d263e41c5f95a2fd4ebdb6280b5c6c3
- https://git.kernel.org/stable/c/4617fb8fc15effe8eda4dd898d4e33eb537a7140
- https://git.kernel.org/stable/c/4d9807048b851d7a58d5bd089c16254af896e4df
- https://git.kernel.org/stable/c/74981f7577d183acad1cd58f74c10d263711a215
- https://git.kernel.org/stable/c/8d8b3f5f4cbfbf6cb0ea4a4d5dc296872b4151eb
- https://git.kernel.org/stable/c/daac4aa1825de0dbc1a6eede2fa7f9fc53f14223
- https://lists.debian.org/debian-lts-announce/2025/03/msg00001.html
- https://lists.debian.org/debian-lts-announce/2025/03/msg00002.html



