Commit 1b06b99f authored by Marc Zyngier's avatar Marc Zyngier

KVM: arm64: Harden __ctxt_sys_reg() against out-of-range values

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: default avatarJoey Gouly <joey.gouly@arm.com>
Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240419102935.1935571-2-maz@kernel.orgSigned-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent fec50db7
...@@ -896,7 +896,7 @@ struct kvm_vcpu_arch { ...@@ -896,7 +896,7 @@ struct kvm_vcpu_arch {
* Don't bother with VNCR-based accesses in the nVHE code, it has no * Don't bother with VNCR-based accesses in the nVHE code, it has no
* business dealing with NV. * 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 !defined (__KVM_NVHE_HYPERVISOR__)
if (unlikely(cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) && 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) ...@@ -906,6 +906,13 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
return (u64 *)&ctxt->sys_regs[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)) #define ctxt_sys_reg(c,r) (*__ctxt_sys_reg(c,r))
u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg); u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment