[PATCH 1/4] KVM: x86: Grab regs_dirty in local 'unsigned long'

From: Sean Christopherson
Date: Wed May 25 2022 - 18:26:43 EST


Capture ctxt->regs_dirty in a local 'unsigned long' instead of casting
ctxt->regs_dirty to an 'unsigned long *' for use in for_each_set_bit().
The bitops helpers really do read the entire 'unsigned long', even though
the walking of the read value is capped at the specified size. I.e. KVM
is reading memory beyond ctxt->regs_dirty. Functionally it's not an
issue because regs_dirty is in the middle of x86_emulate_ctxt, i.e. KVM
is just reading its own memory, but relying on that coincidence is gross
and unsafe.

Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/emulate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 89b11e7dca8a..7226a127ccb4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -269,9 +269,10 @@ static ulong *reg_rmw(struct x86_emulate_ctxt *ctxt, unsigned nr)

static void writeback_registers(struct x86_emulate_ctxt *ctxt)
{
+ unsigned long dirty = ctxt->regs_dirty;
unsigned reg;

- for_each_set_bit(reg, (ulong *)&ctxt->regs_dirty, 16)
+ for_each_set_bit(reg, &dirty, 16)
ctxt->ops->write_gpr(ctxt, reg, ctxt->_regs[reg]);
}

--
2.36.1.124.g0e6072fb45-goog