CVE-2024-26958

Severity CVSS v4.0:
Pending analysis
Type:
CWE-416 Use After Free
Publication date:
01/05/2024
Last modified:
28/08/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> nfs: fix UAF in direct writes<br /> <br /> In production we have been hitting the following warning consistently<br /> <br /> ------------[ cut here ]------------<br /> refcount_t: underflow; use-after-free.<br /> WARNING: CPU: 17 PID: 1800359 at lib/refcount.c:28 refcount_warn_saturate+0x9c/0xe0<br /> Workqueue: nfsiod nfs_direct_write_schedule_work [nfs]<br /> RIP: 0010:refcount_warn_saturate+0x9c/0xe0<br /> PKRU: 55555554<br /> Call Trace:<br /> <br /> ? __warn+0x9f/0x130<br /> ? refcount_warn_saturate+0x9c/0xe0<br /> ? report_bug+0xcc/0x150<br /> ? handle_bug+0x3d/0x70<br /> ? exc_invalid_op+0x16/0x40<br /> ? asm_exc_invalid_op+0x16/0x20<br /> ? refcount_warn_saturate+0x9c/0xe0<br /> nfs_direct_write_schedule_work+0x237/0x250 [nfs]<br /> process_one_work+0x12f/0x4a0<br /> worker_thread+0x14e/0x3b0<br /> ? ZSTD_getCParams_internal+0x220/0x220<br /> kthread+0xdc/0x120<br /> ? __btf_name_valid+0xa0/0xa0<br /> ret_from_fork+0x1f/0x30<br /> <br /> This is because we&amp;#39;re completing the nfs_direct_request twice in a row.<br /> <br /> The source of this is when we have our commit requests to submit, we<br /> process them and send them off, and then in the completion path for the<br /> commit requests we have<br /> <br /> if (nfs_commit_end(cinfo.mds))<br /> nfs_direct_write_complete(dreq);<br /> <br /> However since we&amp;#39;re submitting asynchronous requests we sometimes have<br /> one that completes before we submit the next one, so we end up calling<br /> complete on the nfs_direct_request twice.<br /> <br /> The only other place we use nfs_generic_commit_list() is in<br /> __nfs_commit_inode, which wraps this call in a<br /> <br /> nfs_commit_begin();<br /> nfs_commit_end();<br /> <br /> Which is a common pattern for this style of completion handling, one<br /> that is also repeated in the direct code with get_dreq()/put_dreq()<br /> calls around where we process events as well as in the completion paths.<br /> <br /> Fix this by using the same pattern for the commit requests.<br /> <br /> Before with my 200 node rocksdb stress running this warning would pop<br /> every 10ish minutes. With my patch the stress test has been running for<br /> several hours without popping.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.10.215 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11 (including) 5.15.154 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 6.1.84 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.2 (including) 6.6.24 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.7.12 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.8 (including) 6.8.3 (excluding)
cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*