// For flags

CVE-2021-46910

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

Severity Score

5.5
*CVSS v3.1

Exploit Likelihood

*EPSS

Affected Versions

*CPE

Public Exploits

0
*Multiple Sources

Exploited in Wild

-
*KEV

Decision

Track
*SSVC
Descriptions

In the Linux kernel, the following vulnerability has been resolved:

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

The debugging code for kmap_local() doubles the number of per-CPU fixmap
slots allocated for kmap_local(), in order to use half of them as guard
regions. This causes the fixmap region to grow downwards beyond the start
of its reserved window if the supported number of CPUs is large, and collide
with the newly added virtual DT mapping right below it, which is obviously
not good.

One manifestation of this is EFI boot on a kernel built with NR_CPUS=32
and CONFIG_DEBUG_KMAP_LOCAL=y, which may pass the FDT in highmem, resulting
in block entries below the fixmap region that the fixmap code misidentifies
as fixmap table entries, and subsequently tries to dereference using a
phys-to-virt translation that is only valid for lowmem. This results in a
cryptic splat such as the one below.

ftrace: allocating 45548 entries in 89 pages
8<--- cut here ---
Unable to handle kernel paging request at virtual address fc6006f0
pgd = (ptrval)
[fc6006f0] *pgd=80000040207003, *pmd=00000000
Internal error: Oops: a06 [#1] SMP ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0+ #382
Hardware name: Generic DT based system
PC is at cpu_ca15_set_pte_ext+0x24/0x30
LR is at __set_fixmap+0xe4/0x118
pc : [<c041ac9c>] lr : [<c04189d8>] psr: 400000d3
sp : c1601ed8 ip : 00400000 fp : 00800000
r10: 0000071f r9 : 00421000 r8 : 00c00000
r7 : 00c00000 r6 : 0000071f r5 : ffade000 r4 : 4040171f
r3 : 00c00000 r2 : 4040171f r1 : c041ac78 r0 : fc6006f0
Flags: nZcv IRQs off FIQs off Mode SVC_32 ISA ARM Segment none
Control: 30c5387d Table: 40203000 DAC: 00000001
Process swapper (pid: 0, stack limit = 0x(ptrval))

So let's limit CONFIG_NR_CPUS to 16 when CONFIG_DEBUG_KMAP_LOCAL=y. Also,
fix the BUILD_BUG_ON() check that was supposed to catch this, by checking
whether the region grows below the start address rather than above the end
address.

En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: ARM: 9063/1: mm: reduce el número máximo de CPU si DEBUG_KMAP_LOCAL está habilitado El código de depuración para kmap_local() duplica el número de ranuras de mapas de reparación por CPU asignadas para kmap_local() , para utilizar la mitad de ellos como regiones de guardia. Esto hace que la región del mapa de arreglos crezca hacia abajo más allá del inicio de su ventana reservada si la cantidad de CPU admitidas es grande, y colisiona con el mapeo de DT virtual recién agregado justo debajo, lo cual obviamente no es bueno. Una manifestación de esto es el arranque EFI en un kernel creado con NR_CPUS=32 y CONFIG_DEBUG_KMAP_LOCAL=y, que puede pasar la FDT en highmem, lo que genera entradas de bloque debajo de la región de fixmap que el código de fixmap identifica erróneamente como entradas de la tabla de fixmap y, posteriormente, intenta desreferencia usando una traducción de phys a virt que solo es válida para lowmem. Esto da como resultado un símbolo críptico como el que se muestra a continuación. ftrace: asignando 45548 entradas en 89 páginas 8&lt;--- cortar aquí --- No se puede manejar la solicitud de paginación del kernel en la dirección virtual fc6006f0 pgd = (ptrval) [fc6006f0] *pgd=80000040207003, *pmd=00000000 Error interno: Ups: a06 [#1] Módulos SMP ARM vinculados en: CPU: 0 PID: 0 Comm: swapper Not tainted 5.11.0+ #382 Nombre del hardware: Sistema genérico basado en DT La PC está en cpu_ca15_set_pte_ext+0x24/0x30 LR está en __set_fixmap+0xe4/ 0x118 pc: [] lr: [] psr: 400000d3 sp: c1601ed8 ip: 00400000 fp: 00800000 r10: 0000071f r9: 00421000 r8: 00c00000 r7: 00c00000 r6: 0000071f r5: ffade000 r4: 4040171f r3: 00c00000 r2: 4040171f r1: c041ac78 r0: fc6006f0 Banderas: nZcv IRQ desactivadas FIQ desactivadas Modo SVC_32 ISA ARM Segmento ninguno Control: 30c5387d Tabla: 40203000 DAC: 00000001 Intercambiador de procesos (pid: 0, límite de pila = 0x(ptr) val)) Así que limitemos CONFIG_NR_CPUS a 16 cuando CONFIG_DEBUG_KMAP_LOCAL=y. Además, corrija la verificación BUILD_BUG_ON() que se suponía detectaría esto, verificando si la región crece por debajo de la dirección inicial en lugar de por encima de la dirección final.

*Credits: N/A
CVSS Scores
Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
* Common Vulnerability Scoring System
SSVC
  • Decision:Track
Exploitation
None
Automatable
No
Tech. Impact
Partial
* Organization's Worst-case Scenario
Timeline
  • 2024-02-25 CVE Reserved
  • 2024-02-27 CVE Published
  • 2024-02-27 EPSS Updated
  • 2024-09-11 CVE Updated
  • ---------- Exploited in Wild
  • ---------- KEV Due Date
  • ---------- First Exploit
CWE
CAPEC
Affected Vendors, Products, and Versions
Vendor Product Version Other Status
Vendor Product Version Other Status <-- --> Vendor Product Version Other Status
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.11 < 5.11.16
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.11 < 5.11.16"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.11 < 5.12
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.11 < 5.12"
en
Affected