CVE-2024-50106
Severity CVSS v4.0:
Pending analysis
Type:
CWE-416
Use After Free
Publication date:
05/11/2024
Last modified:
12/11/2024
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
nfsd: fix race between laundromat and free_stateid<br />
<br />
There is a race between laundromat handling of revoked delegations<br />
and a client sending free_stateid operation. Laundromat thread<br />
finds that delegation has expired and needs to be revoked so it<br />
marks the delegation stid revoked and it puts it on a reaper list<br />
but then it unlock the state lock and the actual delegation revocation<br />
happens without the lock. Once the stid is marked revoked a racing<br />
free_stateid processing thread does the following (1) it calls<br />
list_del_init() which removes it from the reaper list and (2) frees<br />
the delegation stid structure. The laundromat thread ends up not<br />
calling the revoke_delegation() function for this particular delegation<br />
but that means it will no release the lock lease that exists on<br />
the file.<br />
<br />
Now, a new open for this file comes in and ends up finding that<br />
lease list isn&#39;t empty and calls nfsd_breaker_owns_lease() which ends<br />
up trying to derefence a freed delegation stateid. Leading to the<br />
followint use-after-free KASAN warning:<br />
<br />
kernel: ==================================================================<br />
kernel: BUG: KASAN: slab-use-after-free in nfsd_breaker_owns_lease+0x140/0x160 [nfsd]<br />
kernel: Read of size 8 at addr ffff0000e73cd0c8 by task nfsd/6205<br />
kernel:<br />
kernel: CPU: 2 UID: 0 PID: 6205 Comm: nfsd Kdump: loaded Not tainted 6.11.0-rc7+ #9<br />
kernel: Hardware name: Apple Inc. Apple Virtualization Generic Platform, BIOS 2069.0.0.0.0 08/03/2024<br />
kernel: Call trace:<br />
kernel: dump_backtrace+0x98/0x120<br />
kernel: show_stack+0x1c/0x30<br />
kernel: dump_stack_lvl+0x80/0xe8<br />
kernel: print_address_description.constprop.0+0x84/0x390<br />
kernel: print_report+0xa4/0x268<br />
kernel: kasan_report+0xb4/0xf8<br />
kernel: __asan_report_load8_noabort+0x1c/0x28<br />
kernel: nfsd_breaker_owns_lease+0x140/0x160 [nfsd]<br />
kernel: nfsd_file_do_acquire+0xb3c/0x11d0 [nfsd]<br />
kernel: nfsd_file_acquire_opened+0x84/0x110 [nfsd]<br />
kernel: nfs4_get_vfs_file+0x634/0x958 [nfsd]<br />
kernel: nfsd4_process_open2+0xa40/0x1a40 [nfsd]<br />
kernel: nfsd4_open+0xa08/0xe80 [nfsd]<br />
kernel: nfsd4_proc_compound+0xb8c/0x2130 [nfsd]<br />
kernel: nfsd_dispatch+0x22c/0x718 [nfsd]<br />
kernel: svc_process_common+0x8e8/0x1960 [sunrpc]<br />
kernel: svc_process+0x3d4/0x7e0 [sunrpc]<br />
kernel: svc_handle_xprt+0x828/0xe10 [sunrpc]<br />
kernel: svc_recv+0x2cc/0x6a8 [sunrpc]<br />
kernel: nfsd+0x270/0x400 [nfsd]<br />
kernel: kthread+0x288/0x310<br />
kernel: ret_from_fork+0x10/0x20<br />
<br />
This patch proposes a fixed that&#39;s based on adding 2 new additional<br />
stid&#39;s sc_status values that help coordinate between the laundromat<br />
and other operations (nfsd4_free_stateid() and nfsd4_delegreturn()).<br />
<br />
First to make sure, that once the stid is marked revoked, it is not<br />
removed by the nfsd4_free_stateid(), the laundromat take a reference<br />
on the stateid. Then, coordinating whether the stid has been put<br />
on the cl_revoked list or we are processing FREE_STATEID and need to<br />
make sure to remove it from the list, each check that state and act<br />
accordingly. If laundromat has added to the cl_revoke list before<br />
the arrival of FREE_STATEID, then nfsd4_free_stateid() knows to remove<br />
it from the list. If nfsd4_free_stateid() finds that operations arrived<br />
before laundromat has placed it on cl_revoke list, it marks the state<br />
freed and then laundromat will no longer add it to the list.<br />
<br />
Also, for nfsd4_delegreturn() when looking for the specified stid,<br />
we need to access stid that are marked removed or freeable, it means<br />
the laundromat has started processing it but hasn&#39;t finished and this<br />
delegreturn needs to return nfserr_deleg_revoked and not<br />
nfserr_bad_stateid. The latter will not trigger a FREE_STATEID and the<br />
lack of it will leave this stid on the cl_revoked list indefinitely.
Impact
Base Score 3.x
7.00
Severity 3.x
HIGH
Vulnerable products and versions
CPE | From | Up to |
---|---|---|
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 3.17 (including) | 6.11.6 (excluding) |
cpe:2.3:o:linux:linux_kernel:6.12:rc1:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc2:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc3:*:*:*:*:*:* | ||
cpe:2.3:o:linux:linux_kernel:6.12:rc4:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page