[PATCH v2 1/4] x86/mm: Don't randomize the CPU entry area with KMSAN

From: Viorel Cernateanu via B4 Relay

Date: Sun Nov 01 2026 - 12:05:41 EST


From: Viorel Cernateanu <vrilutza@xxxxxxxxx>

arch_kmsan_get_meta_or_null() derives the CPU number from the offset
of an address within the CPU entry area. This assumes that the areas
are laid out in CPU order.

With KASLR, init_cea_offsets() assigns each CPU a random slot. The
metadata lookup treats that slot number as a CPU number and can pass
an out-of-range index to get_cpu_entry_area().

On an Ivy Bridge laptop, this causes a KMSAN kernel to oops during
boot while the hard lockup detector sets up its perf event. A QEMU
test that reads one byte from the current CPU's GDT alias reproduces
the out-of-bounds access:

UBSAN: array-index-out-of-bounds in arch/x86/mm/cpu_entry_area.c:25:9
index 2100006 is out of range for type 'unsigned long[64]'
RIP: 0010:get_cpu_entry_area+0x14/0x50

Keep the CPU entry areas in CPU order when KMSAN is enabled. This
allows the metadata lookup to identify the CPU directly, without
searching every CPU's area on each lookup.

This disables CPU entry area randomization for KMSAN kernels.
Kernel text randomization remains enabled.

Fixes: 97e3d26b5e5f ("x86/mm: Randomize per-cpu entry area")
Suggested-by: Alexander Potapenko <glider@xxxxxxxxxx>
Signed-off-by: Viorel Cernateanu <vrilutza@xxxxxxxxx>
---
arch/x86/mm/cpu_entry_area.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
index 575f863f3c75..ce9b5d0e968d 100644
--- a/arch/x86/mm/cpu_entry_area.c
+++ b/arch/x86/mm/cpu_entry_area.c
@@ -30,7 +30,11 @@ static __init void init_cea_offsets(void)
unsigned int max_cea;
unsigned int i, j;

- if (!kaslr_enabled()) {
+ /*
+ * KMSAN works out the CPU of a CPU entry area address from its offset,
+ * see arch_kmsan_get_meta_or_null(), so keep the areas in CPU order.
+ */
+ if (!kaslr_enabled() || IS_ENABLED(CONFIG_KMSAN)) {
for_each_possible_cpu(i)
per_cpu(_cea_offset, i) = i;
return;

--
2.53.0