]> www.infradead.org Git - nvme.git/commitdiff
KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values
authorMarc Zyngier <maz@kernel.org>
Fri, 19 Apr 2024 10:29:21 +0000 (11:29 +0100)
committerMarc Zyngier <maz@kernel.org>
Sat, 20 Apr 2024 11:42:47 +0000 (12:42 +0100)
The unsuspecting kernel tinkerer can be easily confused into
writing something that looks like this:

ikey.lo = __vcpu_sys_reg(vcpu, SYS_APIAKEYLO_EL1);

which seems vaguely sensible, until you realise that the second
parameter is the encoding of a sysreg, and not the index into
the vcpu sysreg file... Debugging what happens in this case is
an interesting exercise in head<->wall interactions.

As they often say: "Any resemblance to actual persons, living
or dead, or actual events is purely coincidental".

In order to save people's time, add some compile-time hardening
that will at least weed out the "stupidly out of range" values.
This will *not* catch anything that isn't a compile-time constant.

Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240419102935.1935571-2-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h

index 9e8a496fb284ea3aff570950fc2b3e15b5e4e586..8eb04c9eb259e83916f5b474c5f89d76eb21ae66 100644 (file)
@@ -896,7 +896,7 @@ struct kvm_vcpu_arch {
  * Don't bother with VNCR-based accesses in the nVHE code, it has no
  * business dealing with NV.
  */
-static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
+static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 {
 #if !defined (__KVM_NVHE_HYPERVISOR__)
        if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
@@ -906,6 +906,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
        return (u64 *)&ctxt->sys_regs[r];
 }
 
+#define __ctxt_sys_reg(c,r)                                            \
+       ({                                                              \
+               BUILD_BUG_ON(__builtin_constant_p(r) &&                 \
+                            (r) >= NR_SYS_REGS);                       \
+               ___ctxt_sys_reg(c, r);                                  \
+       })
+
 #define ctxt_sys_reg(c,r)      (*__ctxt_sys_reg(c,r))
 
 u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);