CVE-2024-56758

Severity CVSS v4.0:
Pending analysis
Type:
CWE-476 NULL Pointer Dereference
Publication date:
06/01/2025
Last modified:
03/11/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> btrfs: check folio mapping after unlock in relocate_one_folio()<br /> <br /> When we call btrfs_read_folio() to bring a folio uptodate, we unlock the<br /> folio. The result of that is that a different thread can modify the<br /> mapping (like remove it with invalidate) before we call folio_lock().<br /> This results in an invalid page and we need to try again.<br /> <br /> In particular, if we are relocating concurrently with aborting a<br /> transaction, this can result in a crash like the following:<br /> <br /> BUG: kernel NULL pointer dereference, address: 0000000000000000<br /> PGD 0 P4D 0<br /> Oops: 0000 [#1] SMP<br /> CPU: 76 PID: 1411631 Comm: kworker/u322:5<br /> Workqueue: events_unbound btrfs_reclaim_bgs_work<br /> RIP: 0010:set_page_extent_mapped+0x20/0xb0<br /> RSP: 0018:ffffc900516a7be8 EFLAGS: 00010246<br /> RAX: ffffea009e851d08 RBX: ffffea009e0b1880 RCX: 0000000000000000<br /> RDX: 0000000000000000 RSI: ffffc900516a7b90 RDI: ffffea009e0b1880<br /> RBP: 0000000003573000 R08: 0000000000000001 R09: ffff88c07fd2f3f0<br /> R10: 0000000000000000 R11: 0000194754b575be R12: 0000000003572000<br /> R13: 0000000003572fff R14: 0000000000100cca R15: 0000000005582fff<br /> FS: 0000000000000000(0000) GS:ffff88c07fd00000(0000) knlGS:0000000000000000<br /> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br /> CR2: 0000000000000000 CR3: 000000407d00f002 CR4: 00000000007706f0<br /> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000<br /> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400<br /> PKRU: 55555554<br /> Call Trace:<br /> <br /> ? __die+0x78/0xc0<br /> ? page_fault_oops+0x2a8/0x3a0<br /> ? __switch_to+0x133/0x530<br /> ? wq_worker_running+0xa/0x40<br /> ? exc_page_fault+0x63/0x130<br /> ? asm_exc_page_fault+0x22/0x30<br /> ? set_page_extent_mapped+0x20/0xb0<br /> relocate_file_extent_cluster+0x1a7/0x940<br /> relocate_data_extent+0xaf/0x120<br /> relocate_block_group+0x20f/0x480<br /> btrfs_relocate_block_group+0x152/0x320<br /> btrfs_relocate_chunk+0x3d/0x120<br /> btrfs_reclaim_bgs_work+0x2ae/0x4e0<br /> process_scheduled_works+0x184/0x370<br /> worker_thread+0xc6/0x3e0<br /> ? blk_add_timer+0xb0/0xb0<br /> kthread+0xae/0xe0<br /> ? flush_tlb_kernel_range+0x90/0x90<br /> ret_from_fork+0x2f/0x40<br /> ? flush_tlb_kernel_range+0x90/0x90<br /> ret_from_fork_asm+0x11/0x20<br /> <br /> <br /> This occurs because cleanup_one_transaction() calls<br /> destroy_delalloc_inodes() which calls invalidate_inode_pages2() which<br /> takes the folio_lock before setting mapping to NULL. We fail to check<br /> this, and subsequently call set_extent_mapping(), which assumes that<br /> mapping != NULL (in fact it asserts that in debug mode)<br /> <br /> Note that the "fixes" patch here is not the one that introduced the<br /> race (the very first iteration of this code from 2009) but a more recent<br /> change that made this particular crash happen in practice.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.1.54 (including) 6.2 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.5.4 (including) 6.12.8 (excluding)
cpe:2.3:o:linux:linux_kernel:6.13:rc1:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.13:rc2:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.13:rc3:*:*:*:*:*:*
cpe:2.3:o:linux:linux_kernel:6.13:rc4:*:*:*:*:*:*