Caller of vmware_hypercall_slow() can pass NULL into *out1, *out2,... *out5. It will lead to a NULL pointer dereference. Check a pointer for NULL before assigning a value. Fixes: 666cbb562d05d ("x86/vmware: Introduce VMware hypercall API") Co-developed-by: Alex James <alex.james@xxxxxxxxxxxx> Signed-off-by: Alex James <alex.james@xxxxxxxxxxxx> Signed-off-by: Alexey Makhalov <alexey.makhalov@xxxxxxxxxxxx> --- arch/x86/kernel/cpu/vmware.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 55903563afd3..16da970499f2 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c @@ -72,13 +72,13 @@ unsigned long vmware_hypercall_slow(unsigned long cmd, u32 *out1, u32 *out2, u32 *out3, u32 *out4, u32 *out5) { - unsigned long out0; + unsigned long out0, rbx, rcx, rdx, rsi, rdi; switch (vmware_hypercall_mode) { case CPUID_VMWARE_FEATURES_ECX_VMCALL: asm_inline volatile ("vmcall" - : "=a" (out0), "=b" (*out1), "=c" (*out2), - "=d" (*out3), "=S" (*out4), "=D" (*out5) + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) : "a" (VMWARE_HYPERVISOR_MAGIC), "b" (in1), "c" (cmd), @@ -89,8 +89,8 @@ unsigned long vmware_hypercall_slow(unsigned long cmd, break; case CPUID_VMWARE_FEATURES_ECX_VMMCALL: asm_inline volatile ("vmmcall" - : "=a" (out0), "=b" (*out1), "=c" (*out2), - "=d" (*out3), "=S" (*out4), "=D" (*out5) + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) : "a" (VMWARE_HYPERVISOR_MAGIC), "b" (in1), "c" (cmd), @@ -101,8 +101,8 @@ unsigned long vmware_hypercall_slow(unsigned long cmd, break; default: asm_inline volatile ("movw %[port], %%dx; inl (%%dx), %%eax" - : "=a" (out0), "=b" (*out1), "=c" (*out2), - "=d" (*out3), "=S" (*out4), "=D" (*out5) + : "=a" (out0), "=b" (rbx), "=c" (rcx), + "=d" (rdx), "=S" (rsi), "=D" (rdi) : [port] "i" (VMWARE_HYPERVISOR_PORT), "a" (VMWARE_HYPERVISOR_MAGIC), "b" (in1), @@ -113,6 +113,18 @@ unsigned long vmware_hypercall_slow(unsigned long cmd, : "cc", "memory"); break; } + + if (out1) + *out1 = rbx; + if (out2) + *out2 = rcx; + if (out3) + *out3 = rdx; + if (out4) + *out4 = rsi; + if (out5) + *out5 = rdi; + return out0; } -- 2.39.4