KVM: arm64: Prevent access to vCPU events before init
Another day, another syzkaller bug. KVM erroneously allows userspace to
pend vCPU events for a vCPU that hasn't been initialized yet, leading to
KVM interpreting a bunch of uninitialized garbage for routing /
injecting the exception.
In one case the injection code and the hyp disagree on whether the vCPU
has a 32bit EL1 and put the vCPU into an illegal mode for AArch64,
tripping the BUG() in exception_target_el() during the next injection:
kernel BUG at arch/arm64/kvm/inject_fault.c:40!
Internal error: Oops - BUG:
00000000f2000800 [#1] SMP
CPU: 3 UID: 0 PID: 318 Comm: repro Not tainted
6.17.0-rc4-00104-g10fd0285305d #6 PREEMPT
Hardware name: linux,dummy-virt (DT)
pstate:
21402009 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
pc : exception_target_el+0x88/0x8c
lr : pend_serror_exception+0x18/0x13c
sp :
ffff800082f03a10
x29:
ffff800082f03a10 x28:
ffff0000cb132280 x27:
0000000000000000
x26:
0000000000000000 x25:
ffff0000c2a99c20 x24:
0000000000000000
x23:
0000000000008000 x22:
0000000000000002 x21:
0000000000000004
x20:
0000000000008000 x19:
ffff0000c2a99c20 x18:
0000000000000000
x17:
0000000000000000 x16:
0000000000000000 x15:
00000000200000c0
x14:
0000000000000000 x13:
0000000000000000 x12:
0000000000000000
x11:
0000000000000000 x10:
0000000000000000 x9 :
0000000000000000
x8 :
ffff800082f03af8 x7 :
0000000000000000 x6 :
0000000000000000
x5 :
ffff800080f621f0 x4 :
0000000000000000 x3 :
0000000000000000
x2 :
000000000040009b x1 :
0000000000000003 x0 :
ffff0000c2a99c20
Call trace:
exception_target_el+0x88/0x8c (P)
kvm_inject_serror_esr+0x40/0x3b4
__kvm_arm_vcpu_set_events+0xf0/0x100
kvm_arch_vcpu_ioctl+0x180/0x9d4
kvm_vcpu_ioctl+0x60c/0x9f4
__arm64_sys_ioctl+0xac/0x104
invoke_syscall+0x48/0x110
el0_svc_common.constprop.0+0x40/0xe0
do_el0_svc+0x1c/0x28
el0_svc+0x34/0xf0
el0t_64_sync_handler+0xa0/0xe4
el0t_64_sync+0x198/0x19c
Code:
f946bc01 b4fffe61 9101e020 17fffff2 (
d4210000)
Reject the ioctls outright as no sane VMM would call these before
KVM_ARM_VCPU_INIT anyway. Even if it did the exception would've been
thrown away by the eventual reset of the vCPU's state.
Cc: stable@vger.kernel.org # 6.17
Fixes: b7b27facc7b5 ("arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS")
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>