Commit 61ed08c2 authored by Breno Leitao's avatar Breno Leitao Committed by Ard Biesheuvel
Browse files

arm64: efi: Fix NULL pointer dereference by initializing user_ns



Linux 6.19-rc2 (9448598b ("Linux 6.19-rc2")) is crashing with a NULL
pointer dereference on arm64 hosts:

  Unable to handle kernel NULL pointer dereference at virtual address 00000000000000c8
   pc : cap_capable (security/commoncap.c:82 security/commoncap.c:128)
   Call trace:
    cap_capable (security/commoncap.c:82 security/commoncap.c:128) (P)
    security_capable (security/security.c:?)
    ns_capable_noaudit (kernel/capability.c:342 kernel/capability.c:381)
    __ptrace_may_access (./include/linux/rcupdate.h:895 kernel/ptrace.c:326)
    ptrace_may_access (kernel/ptrace.c:353)
    do_task_stat (fs/proc/array.c:467)
    proc_tgid_stat (fs/proc/array.c:673)
    proc_single_show (fs/proc/base.c:803)

I've bissected the problem to commit a5baf582 ("arm64/efi: Call EFI
runtime services without disabling preemption").

>From my analyzes, the crash occurs because efi_mm lacks a user_ns field
initialization. This was previously harmless, but commit a5baf582
("arm64/efi: Call EFI runtime services without disabling preemption")
changed the EFI runtime call path to use kthread_use_mm(&efi_mm), which
temporarily adopts efi_mm as the current mm for the calling kthread.

When a thread has an active mm, LSM hooks like cap_capable() expect
mm->user_ns to be valid for credential checks. With efi_mm.user_ns being
NULL, capability checks during possible /proc access dereference the
NULL pointer and crash.

Fix by initializing efi_mm.user_ns to &init_user_ns.

Fixes: a5baf582 ("arm64/efi: Call EFI runtime services without disabling preemption")
Signed-off-by: default avatarBreno Leitao <leitao@debian.org>
Acked-by: default avatarRik van Riel <riel@surriel.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 5688e977
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ struct mm_struct efi_mm = {
	MMAP_LOCK_INITIALIZER(efi_mm)
	.page_table_lock	= __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
	.mmlist			= LIST_HEAD_INIT(efi_mm.mmlist),
	.user_ns		= &init_user_ns,
	.cpu_bitmap		= { [BITS_TO_LONGS(NR_CPUS)] = 0},
#ifdef CONFIG_SCHED_MM_CID
	.mm_cid.lock		= __RAW_SPIN_LOCK_UNLOCKED(efi_mm.mm_cid.lock),