nvmx_handle_vmwrite leaves local eight byte variable 'operand'
uninitialised to be written as an out-parameter by decode_vmx_inst. In
cases where the operand to vmwrite is a 32 bit memory operand, the
invokation of hvm_copy_from_guest_linear leaves the upper half of
*poperandS uninitialised. The resulting eight byte value is consequently
written to the vmcs12 leaking the four uninitialised bytes into guest
physical memory.
Initialize the stack-space passed to decode_vmx_inst to avoid this
issue.
Fixes: 2b2793d3ae44 ("nEPT: handle invept instruction from L1 VMM")
Fixes: d4c5b9db5a85 ("Nested VMX: Emulation of guest VMWRITE")
Fixes: 9ccf55307868 ("nVMX: virutalize VPID capability to nested VMM")
Signed-off-by: Johann Höpfner <hoepf@cit.tum.de>
---
> In any event - why don't you make your proposed change into a proper patch
> (primary piece missing is your S-o-b, and perhaps we also would want a
> suitable Fixes: tag)?
Sorry to have kept you waiting. Here is the formatted patch. I included
the invvpid case still, though I believe only vmwrite remains after the
patch you linked is merged, right?
xen/arch/x86/hvm/vmx/vvmx.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index e4cdfe55c1..68c5df6658 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -1968,7 +1968,7 @@ static int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
{
struct vcpu *v = current;
struct vmx_inst_decoded decode;
- unsigned long operand;
+ unsigned long operand = 0;
u64 vmcs_encoding;
enum vmx_insn_errno err;
int rc;
@@ -2012,7 +2012,7 @@ static int nvmx_handle_vmwrite(struct cpu_user_regs *regs)
static int nvmx_handle_invept(struct cpu_user_regs *regs)
{
struct vmx_inst_decoded decode;
- unsigned long eptp;
+ unsigned long eptp = 0;
int ret;
if ( (ret = decode_vmx_inst(regs, &decode, &eptp)) != X86EMUL_OKAY )
@@ -2040,7 +2040,7 @@ static int nvmx_handle_invept(struct cpu_user_regs *regs)
static int nvmx_handle_invvpid(struct cpu_user_regs *regs)
{
struct vmx_inst_decoded decode;
- unsigned long vpid;
+ unsigned long vpid = 0;
int ret;
if ( (ret = decode_vmx_inst(regs, &decode, &vpid)) != X86EMUL_OKAY )
--
2.53.0
On 07.08.2026 11:32, Johann Höpfner wrote:
> nvmx_handle_vmwrite leaves local eight byte variable 'operand'
> uninitialised to be written as an out-parameter by decode_vmx_inst. In
> cases where the operand to vmwrite is a 32 bit memory operand, the
> invokation of hvm_copy_from_guest_linear leaves the upper half of
> *poperandS uninitialised. The resulting eight byte value is consequently
> written to the vmcs12 leaking the four uninitialised bytes into guest
> physical memory.
>
> Initialize the stack-space passed to decode_vmx_inst to avoid this
> issue.
>
> Fixes: 2b2793d3ae44 ("nEPT: handle invept instruction from L1 VMM")
> Fixes: d4c5b9db5a85 ("Nested VMX: Emulation of guest VMWRITE")
> Fixes: 9ccf55307868 ("nVMX: virutalize VPID capability to nested VMM")
> Signed-off-by: Johann Höpfner <hoepf@cit.tum.de>
> ---
>
>> In any event - why don't you make your proposed change into a proper patch
>> (primary piece missing is your S-o-b, and perhaps we also would want a
>> suitable Fixes: tag)?
>
> Sorry to have kept you waiting. Here is the formatted patch. I included
> the invvpid case still, though I believe only vmwrite remains after the
> patch you linked is merged, right?
I think so, yes. Andrew, Roger - any chance of coming to a conclusion on that
much earlier work [1]? Imo that wants to go in first, with the patch here then
shrunk to what's actually still needed (at which point only a single Fixes:
would be left as well).
Jan
[1] https://lists.xen.org/archives/html/xen-devel/2025-06/msg01208.html
© 2016 - 2026 Red Hat, Inc.