Bug 2266414 (CVE-2021-46910) - CVE-2021-46910 kernel: kmap_local() doubles the number of per-CPU
Summary: CVE-2021-46910 kernel: kmap_local() doubles the number of per-CPU
Keywords:
Status: NEW
Alias: CVE-2021-46910
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2266417
Blocks: 2266369
TreeView+ depends on / blocked
 
Reported: 2024-02-27 18:58 UTC by Rohit Keshri
Modified: 2024-03-26 18:32 UTC (History)
49 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in kmap_local() in the Linux Kernel that doubles the number of per-CPU fixmap slots allocated for kmap_local(). This causes the fixmap region to grow downwards beyond the start of its reserved window if the supported number of CPUs is large, eventually colliding with the newly added virtual DT mapping below it.
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description Rohit Keshri 2024-02-27 18:58:54 UTC
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.

https://git.kernel.org/stable/c/5965ac11b1d5fcb38464728931649cd9df79c7c9
https://git.kernel.org/stable/c/d624833f5984d484c5e3196f34b926f9e71dafee

Comment 1 Rohit Keshri 2024-02-27 19:07:41 UTC
Created kernel tracking bugs for this issue:

Affects: fedora-all [bug 2266417]

Comment 3 Justin M. Forbes 2024-02-27 23:08:58 UTC
This was fixed for Fedora with the 5.11.16 stable kernel updates.


Note You need to log in before you can comment on or make changes to this bug.