CVE-2024-40899

Severity CVSS v4.0:
Pending analysis
Type:
CWE-416 Use After Free
Publication date:
12/07/2024
Last modified:
03/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()<br /> <br /> We got the following issue in a fuzz test of randomly issuing the restore<br /> command:<br /> <br /> ==================================================================<br /> BUG: KASAN: slab-use-after-free in cachefiles_ondemand_daemon_read+0x609/0xab0<br /> Write of size 4 at addr ffff888109164a80 by task ondemand-04-dae/4962<br /> <br /> CPU: 11 PID: 4962 Comm: ondemand-04-dae Not tainted 6.8.0-rc7-dirty #542<br /> Call Trace:<br /> kasan_report+0x94/0xc0<br /> cachefiles_ondemand_daemon_read+0x609/0xab0<br /> vfs_read+0x169/0xb50<br /> ksys_read+0xf5/0x1e0<br /> <br /> Allocated by task 626:<br /> __kmalloc+0x1df/0x4b0<br /> cachefiles_ondemand_send_req+0x24d/0x690<br /> cachefiles_create_tmpfile+0x249/0xb30<br /> cachefiles_create_file+0x6f/0x140<br /> cachefiles_look_up_object+0x29c/0xa60<br /> cachefiles_lookup_cookie+0x37d/0xca0<br /> fscache_cookie_state_machine+0x43c/0x1230<br /> [...]<br /> <br /> Freed by task 626:<br /> kfree+0xf1/0x2c0<br /> cachefiles_ondemand_send_req+0x568/0x690<br /> cachefiles_create_tmpfile+0x249/0xb30<br /> cachefiles_create_file+0x6f/0x140<br /> cachefiles_look_up_object+0x29c/0xa60<br /> cachefiles_lookup_cookie+0x37d/0xca0<br /> fscache_cookie_state_machine+0x43c/0x1230<br /> [...]<br /> ==================================================================<br /> <br /> Following is the process that triggers the issue:<br /> <br /> mount | daemon_thread1 | daemon_thread2<br /> ------------------------------------------------------------<br /> cachefiles_ondemand_init_object<br /> cachefiles_ondemand_send_req<br /> REQ_A = kzalloc(sizeof(*req) + data_len)<br /> wait_for_completion(&amp;REQ_A-&gt;done)<br /> <br /> cachefiles_daemon_read<br /> cachefiles_ondemand_daemon_read<br /> REQ_A = cachefiles_ondemand_select_req<br /> cachefiles_ondemand_get_fd<br /> copy_to_user(_buffer, msg, n)<br /> process_open_req(REQ_A)<br /> ------ restore ------<br /> cachefiles_ondemand_restore<br /> xas_for_each(&amp;xas, req, ULONG_MAX)<br /> xas_set_mark(&amp;xas, CACHEFILES_REQ_NEW);<br /> <br /> cachefiles_daemon_read<br /> cachefiles_ondemand_daemon_read<br /> REQ_A = cachefiles_ondemand_select_req<br /> <br /> write(devfd, ("copen %u,%llu", msg-&gt;msg_id, size));<br /> cachefiles_ondemand_copen<br /> xa_erase(&amp;cache-&gt;reqs, id)<br /> complete(&amp;REQ_A-&gt;done)<br /> kfree(REQ_A)<br /> cachefiles_ondemand_get_fd(REQ_A)<br /> fd = get_unused_fd_flags<br /> file = anon_inode_getfile<br /> fd_install(fd, file)<br /> load = (void *)REQ_A-&gt;msg.data;<br /> load-&gt;fd = fd;<br /> // load UAF !!!<br /> <br /> This issue is caused by issuing a restore command when the daemon is still<br /> alive, which results in a request being processed multiple times thus<br /> triggering a UAF. So to avoid this problem, add an additional reference<br /> count to cachefiles_req, which is held while waiting and reading, and then<br /> released when the waiting and reading is over.<br /> <br /> Note that since there is only one reference count for waiting, we need to<br /> avoid the same request being completed multiple times, so we can only<br /> complete the request if it is successfully removed from the xarray.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.8 (including) 6.9.6 (excluding)
cpe:2.3:o:linux:linux_kernel:6.10:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.10:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.10:rc3:*:*:*:*:*:*