CVE-2022-48731 in Linux
Summary
by MITRE • 06/20/2024
In the Linux kernel, the following vulnerability has been resolved:
mm/kmemleak: avoid scanning potential huge holes
When using devm_request_free_mem_region() and devm_memremap_pages() to add ZONE_DEVICE memory, if requested free mem region's end pfn were huge(e.g., 0x400000000), the node_end_pfn() will be also huge (see move_pfn_range_to_zone()). Thus it creates a huge hole between node_start_pfn() and node_end_pfn().
We found on some AMD APUs, amdkfd requested such a free mem region and created a huge hole. In such a case, following code snippet was just doing busy test_bit() looping on the huge hole.
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
struct page *page = pfn_to_online_page(pfn); if (!page) continue; ... }
So we got a soft lockup:
watchdog: BUG: soft lockup - CPU#6 stuck for 26s! [bash:1221]
CPU: 6 PID: 1221 Comm: bash Not tainted 5.15.0-custom #1 RIP: 0010:pfn_to_online_page+0x5/0xd0 Call Trace: ? kmemleak_scan+0x16a/0x440 kmemleak_write+0x306/0x3a0 ? common_file_perm+0x72/0x170 full_proxy_write+0x5c/0x90 vfs_write+0xb9/0x260 ksys_write+0x67/0xe0 __x64_sys_write+0x1a/0x20 do_syscall_64+0x3b/0xc0 entry_SYSCALL_64_after_hwframe+0x44/0xae
I did some tests with the patch.
(1) amdgpu module unloaded
before the patch:
real 0m0.976s user 0m0.000s sys 0m0.968s
after the patch:
real 0m0.981s user 0m0.000s sys 0m0.973s
(2) amdgpu module loaded
before the patch:
real 0m35.365s user 0m0.000s sys 0m35.354s
after the patch:
real 0m1.049s user 0m0.000s sys 0m1.042s
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/30/2024
The vulnerability described in CVE-2022-48731 resides within the Linux kernel's memory management subsystem, specifically in the kmemleak component responsible for tracking kernel memory allocations. This issue manifests when device memory regions are dynamically allocated using devm_request_free_mem_region() and devm_memremap_pages() functions, particularly affecting systems with ZONE_DEVICE memory configuration. The flaw occurs when the requested memory region's ending page frame number (pfn) becomes extremely large, creating what is termed a "huge hole" in the memory map between node_start_pfn() and node_end_pfn(). This condition is particularly prevalent on certain AMD APUs where the amdkfd driver requests such memory regions, resulting in memory mapping artifacts that cause significant performance degradation.
The technical root cause involves the kmemleak scanning mechanism which iterates through memory pages using a simple loop structure that processes each page frame number individually. When a huge memory hole exists, this loop becomes extremely inefficient as it continuously executes test_bit() operations on massive ranges of non-existent memory pages. The specific code pattern that triggers the issue is the straightforward for loop iterating from start_pfn to end_pfn, where end_pfn can reach values as large as 0x400000000, causing the system to spend enormous amounts of time processing non-existent memory pages rather than actual kernel memory allocations. This behavior directly violates the principle of efficient memory management and creates a denial of service condition that can lead to system lockups.
The operational impact of this vulnerability is severe and measurable, as demonstrated by the performance testing results showing dramatic degradation. Without the patch, when the amdgpu module is loaded, system response time increases from approximately 1 second to over 35 seconds, representing a more than thirty-fivefold slowdown in memory scanning operations. This performance degradation directly translates to system instability and potential soft lockups, as evidenced by the watchdog timer reporting a soft lockup where CPU#6 becomes stuck for 26 seconds while executing the pfn_to_online_page function. The vulnerability affects system responsiveness and can cause complete system unresponsiveness during memory scanning operations, particularly in embedded systems or server environments where such memory configurations are common.
The mitigation strategy involves modifying the kmemleak scanning algorithm to avoid traversing these huge memory holes that are created by device memory allocation patterns. The patch implements a more intelligent scanning approach that recognizes when memory regions contain large gaps and skips over these areas efficiently rather than performing expensive bit testing operations on thousands of consecutive page frame numbers. This solution aligns with security best practices for memory management and system stability, ensuring that kernel memory tracking mechanisms do not become bottlenecks or sources of system instability. The fix directly addresses the underlying issue by preventing the inefficient iteration pattern that causes the soft lockup conditions, thereby maintaining system responsiveness while preserving the core functionality of memory leak detection. This vulnerability demonstrates the importance of considering edge cases in memory management algorithms and highlights the need for robust handling of device-specific memory allocation patterns in kernel subsystems.