Skip to content

Commit 2c67e68

Browse files
Wanpeng LiNiranjan Yadla
authored andcommitted
KVM: x86: Fix load damaged SSEx MXCSR register
commit a575813 upstream. Reported by syzkaller: BUG: unable to handle kernel paging request at ffffffffc07f6a2e IP: report_bug+0x94/0x120 PGD 348e12067 P4D 348e12067 PUD 348e14067 PMD 3cbd84067 PTE 80000003f7e87161 Oops: 0003 [#1] SMP CPU: 2 PID: 7091 Comm: kvm_load_guest_ Tainted: G OE 4.11.0+ 96boards#8 task: ffff92fdfb525400 task.stack: ffffbda6c3d04000 RIP: 0010:report_bug+0x94/0x120 RSP: 0018:ffffbda6c3d07b20 EFLAGS: 00010202 do_trap+0x156/0x170 do_error_trap+0xa3/0x170 ? kvm_load_guest_fpu.part.175+0x12a/0x170 [kvm] ? mark_held_locks+0x79/0xa0 ? retint_kernel+0x10/0x10 ? trace_hardirqs_off_thunk+0x1a/0x1c do_invalid_op+0x20/0x30 invalid_op+0x1e/0x30 RIP: 0010:kvm_load_guest_fpu.part.175+0x12a/0x170 [kvm] ? kvm_load_guest_fpu.part.175+0x1c/0x170 [kvm] kvm_arch_vcpu_ioctl_run+0xed6/0x1b70 [kvm] kvm_vcpu_ioctl+0x384/0x780 [kvm] ? kvm_vcpu_ioctl+0x384/0x780 [kvm] ? sched_clock+0x13/0x20 ? __do_page_fault+0x2a0/0x550 do_vfs_ioctl+0xa4/0x700 ? up_read+0x1f/0x40 ? __do_page_fault+0x2a0/0x550 SyS_ioctl+0x79/0x90 entry_SYSCALL_64_fastpath+0x23/0xc2 SDM mentioned that "The MXCSR has several reserved bits, and attempting to write a 1 to any of these bits will cause a general-protection exception(#GP) to be generated". The syzkaller forks' testcase overrides xsave area w/ random values and steps on the reserved bits of MXCSR register. The damaged MXCSR register values of guest will be restored to SSEx MXCSR register before vmentry. This patch fixes it by catching userspace override MXCSR register reserved bits w/ random values and bails out immediately. Reported-by: Andrey Konovalov <[email protected]> Reviewed-by: Paolo Bonzini <[email protected]> Cc: Paolo Bonzini <[email protected]> Cc: Radim Krčmář <[email protected]> Signed-off-by: Wanpeng Li <[email protected]> Signed-off-by: Radim Krčmář <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 733869d commit 2c67e68

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

arch/x86/kernel/fpu/init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
9696
* Boot time FPU feature detection code:
9797
*/
9898
unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
99+
EXPORT_SYMBOL_GPL(mxcsr_feature_mask);
99100

100101
static void __init fpu__init_system_mxcsr(void)
101102
{

arch/x86/kvm/x86.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,23 +3140,28 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
31403140
}
31413141
}
31423142

3143+
#define XSAVE_MXCSR_OFFSET 24
3144+
31433145
static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
31443146
struct kvm_xsave *guest_xsave)
31453147
{
31463148
u64 xstate_bv =
31473149
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
3150+
u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];
31483151

31493152
if (cpu_has_xsave) {
31503153
/*
31513154
* Here we allow setting states that are not present in
31523155
* CPUID leaf 0xD, index 0, EDX:EAX. This is for compatibility
31533156
* with old userspace.
31543157
*/
3155-
if (xstate_bv & ~kvm_supported_xcr0())
3158+
if (xstate_bv & ~kvm_supported_xcr0() ||
3159+
mxcsr & ~mxcsr_feature_mask)
31563160
return -EINVAL;
31573161
load_xsave(vcpu, (u8 *)guest_xsave->region);
31583162
} else {
3159-
if (xstate_bv & ~XFEATURE_MASK_FPSSE)
3163+
if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
3164+
mxcsr & ~mxcsr_feature_mask)
31603165
return -EINVAL;
31613166
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
31623167
guest_xsave->region, sizeof(struct fxregs_state));

0 commit comments

Comments
 (0)