Re: [PATCH v1 09/11] KVM: arm64: Minimise EL2's exposure of host VGIC state during world switch
Fuad Tabba <[email protected]> Thu, 6 Aug 2026 11:05:16 +0100
| Newsgroups | dev.linux.lists.kvmarm,dev.linux.lists.sashiko-reviews |
|---|---|
| Message-ID | <CA+EHjTxiHyuw5EjWLha1OySm3xjRH6rbk41On+5V2+ig1FdCmg@mail.gmail.com> |
Hi folks, On Fri, 12 Jun 2026 at 09:05, Fuad Tabba <[email protected]> wrote: ... > > Pre-existing issues: > > - [Critical] The GICv5 equivalents of the VGIC save/restore hypercalls (`handle___vgic_v5_save_apr` and `handle___vgic_v5_restore_vmcr_apr`) directly dereference host-provided pointers without validation, allowing a complete bypass of pKVM isolation. ... > > > + } else { > > > + __vgic_v3_save_aprs(&host_vcpu->arch.vgic_cpu.vgic_v3); > > > + } > > > } > > > > [Severity: Critical] > > This is a pre-existing issue, but while this patch addresses the VGIC v3 host > > pointer dereference bypass by using get_host_hyp_vcpus_from_vgic_v3_cpu_if(), > > does the same pKVM isolation bypass exist in the GICv5 equivalents? > > GICv5 is not supported in protected mode. vgic-v5.c:62-64 skips > GICv5 registration entirely when is_protected_kvm_enabled(), so no > GICv5-based guest can be created under pKVM. The host never reaches > these hypercalls through any legitimate code path. I was wrong here. skip_v5 only stops the host's own KVM from registering a GICv5 vgic, so the host can still call __vgic_v5_save_apr and __vgic_v5_restore_vmcr_apr. vgic_model has the same gap. EL2 copies it out of the host's `struct kvm` without validating it, so a host can steer the world switch into the GICv5 registers, which are UNDEFINED without FEAT_GCIE. That takes an UNDEF at EL2 and panics the hypervisor. I reproduced it under QEMU on a GICv3 machine. I have sent a series for both [1]. The wider point is that "pKVM does not support GICv5" does not imply "EL2 cannot get there", which is what I had assumed, so it might be worth another look at the newer hypercalls in Sascha's IRS series on that basis [2]. Cheers, /fuad [1] https://lore.kernel.org/all/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ > > > > > Looking at handle___vgic_v5_save_apr() and handle___vgic_v5_restore_vmcr_apr() > > in arch/arm64/kvm/hyp/nvhe/hyp-main.c: > > > > handle___vgic_v5_save_apr(struct kvm_cpu_context *host_ctxt) { > > DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1); > > __vgic_v5_save_apr(kern_hyp_va(cpu_if)); > > } > > > > These handlers appear to take a cpu_if pointer directly from the untrusted > > host context and apply kern_hyp_va() without validation. Could a malicious > > host provide an address that translates to an arbitrary EL2-private memory > > location, granting an arbitrary write or read primitive when > > __vgic_v5_save_apr() or __vgic_v5_restore_vmcr_apr() is invoked? > > > > [Severity: Critical] > > This is also a pre-existing issue, but does a similar arbitrary memory > > corruption primitive exist in handle___kvm_adjust_pc()? > > Yes, pre-existing. It is addressed later in this series by > "Prevent host PC adjustments for protected vCPUs" (patch 10/11). > > Cheers, > /fuad > > > > > Looking at handle___kvm_adjust_pc() in arch/arm64/kvm/hyp/nvhe/hyp-main.c: > > > > static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt) { > > DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); > > __kvm_adjust_pc(kern_hyp_va(vcpu)); > > } > > > > And __kvm_adjust_pc() in arch/arm64/kvm/hyp/exception.c: > > > > void __kvm_adjust_pc(struct kvm_vcpu *vcpu) { > > if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) { > > kvm_inject_exception(vcpu); > > vcpu_clear_flag(vcpu, PENDING_EXCEPTION); > > vcpu_clear_flag(vcpu, EXCEPT_MASK); > > } > > ... > > } > > > > It seems the host-provided vcpu pointer is converted via kern_hyp_va() > > without the __get_host_hyp_vcpus() validation barrier. Could a malicious > > host inject a pointer that translates into EL2-private memory (like > > hypervisor page tables) and set the PENDING_EXCEPTION bit, forcing > > __kvm_adjust_pc() to write exception vector addresses and clear flags at > > specific offsets within the target structure? > > > > -- > > Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=9