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&amp;#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&amp;#39;s based on adding 2 new additional<br /> stid&amp;#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&amp;#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.

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:*:*:*:*:*:*