A vulnerability has been discovered in the Linux kernel, specifically relating to the ARM architecture. This issue has been addressed in the ARM MM (Memory Management) subsystem by reducing the maximum number of CPUs allowed when DEBUG_KMAP_LOCAL is enabled. In this post, we will dive into the details of this vulnerability, its impact, and the solution implemented to resolve it.

Vulnerability Details

The problem lies in the debugging code for kmap_local(), which doubles the number of per-CPU fixmap slots allocated for kmap_local(). This is done to use half of these slots as guard regions. When the supported number of CPUs is large, the fixmap region grows downwards beyond the start of its reserved window and collides with the newly added virtual DT (Device Tree) mapping right below it, causing issues.

One example of this issue can be observed when the kernel is built with NR_CPUS=32 and CONFIG_DEBUG_KMAP_LOCAL=y, specifically when booting with an EFI (Extensible Firmware Interface) enabled system. This configuration may result in the FDT (Flattened Device Tree) being passed in high memory, causing block entries below the fixmap region to be misidentified as fixmap table entries. The fixmap code then tries to dereference these entries using a phys-to-virt translation, which is only valid for low memory.

This results in a cryptic error message like the following one

ftrace: allocating 45548 entries in 89 pages
8<--- cut here ---
Unable to handle kernel paging request at virtual address fc6006f
pgd = (ptrval)
[fc6006f] *pgd=80000040207003, *pmd=00000000
Internal error: Oops: a06 [#1] SMP ARM

Resolution

To fix this vulnerability, the solution implemented is to limit CONFIG_NR_CPUS to 16 when CONFIG_DEBUG_KMAP_LOCAL=y. Additionally, the BUILD_BUG_ON() check that was previously designed to catch this issue has been updated. Instead of checking whether the region grows above the end address, it now checks if the region grows below the start address.

This vulnerability has been resolved in the Linux kernel with the following commit

- ARM: 9063/1: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled

More information about the vulnerability and its impact can be found in the following resources

- CVE-2021-46910 in the National Vulnerability Database (NVD)
- Linux Kernel Mailing List (LKML): ARM: 9063/1: mm: reduce maximum number of CPUs if DEBUG_KMAP_LOCAL is enabled

Conclusion

By addressing this vulnerability, Linux kernel developers have reduced the potential risk of memory corruption and resulting errors when booting EFI-enabled systems with large numbers of CPUs and CONFIG_DEBUG_KMAP_LOCAL=y. Users should ensure that they are running an updated kernel with the resolution in place to avoid running into this issue.

Timeline

Published on: 02/27/2024 07:15:07 UTC
Last modified on: 04/17/2024 16:55:44 UTC