Messages in this thread Patch in this message | | | From | "Chang S. Bae" <> | Subject | [PATCH 1/1] x86/fpu: Fix copy_xstate_to_uabi() to copy init states correctly | Date | Tue, 18 Oct 2022 15:13:49 -0700 |
| |
When an extended state component is present in fpstate, but in init state, the function copies from init_fpstate via copy_feature().
But, dynamic states are not present in init_fpstate. Then accessing init_fpstate for those will explode like this:
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:memcpy_erms+0x6/0x10 ? __copy_xstate_to_uabi_buf+0x381/0x870 fpu_copy_guest_fpstate_to_uabi+0x28/0x80 kvm_arch_vcpu_ioctl+0x14c/0x1460 [kvm] ? __this_cpu_preempt_check+0x13/0x20 ? vmx_vcpu_put+0x2e/0x260 [kvm_intel] kvm_vcpu_ioctl+0xea/0x6b0 [kvm] ? kvm_vcpu_ioctl+0xea/0x6b0 [kvm] ? __fget_light+0xd4/0x130 __x64_sys_ioctl+0xe3/0x910 ? debug_smp_processor_id+0x17/0x20 ? fpregs_assert_state_consistent+0x27/0x50 do_syscall_64+0x3f/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Instead of referencing init_fpstate, simply zero out the userspace buffer for the state component in an all-zeros init state.
Fixes: 2308ee57d93d ("x86/fpu/amx: Enable the AMX feature in 64-bit mode") Reported-by: Yuan Yao <yuan.yao@intel.com> Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com> Tested-by: Yuan Yao <yuan.yao@intel.com> Cc: x86@kernel.org Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/lkml/BYAPR11MB3717EDEF2351C958F2C86EED95259@BYAPR11MB3717.namprd11.prod.outlook.com/ --- arch/x86/kernel/fpu/xstate.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index e77cabfa802f..efa9e3a269fc 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -1141,10 +1141,14 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate, */ pkru.pkru = pkru_val; membuf_write(&to, &pkru, sizeof(pkru)); + } else if (!(header.xfeatures & BIT_ULL(i))) { + /* + * Every extended state component has an all zeros + * init state. + */ + membuf_zero(&to, xstate_sizes[i]); } else { - copy_feature(header.xfeatures & BIT_ULL(i), &to, - __raw_xsave_addr(xsave, i), - __raw_xsave_addr(xinit, i), + membuf_write(&to, __raw_xsave_addr(xsave, i), xstate_sizes[i]); } /* -- 2.17.1
| |