Bug 204177

Summary: PT: Missing filtering on the MSRs
Product: Virtualization Reporter: Maxime Villard (max)
Component: kvmAssignee: virtualization_kvm
Status: NEW ---    
Severity: normal CC: nilal
Priority: P1    
Hardware: Intel   
OS: Linux   
Kernel Version: 5.* Subsystem:
Regression: No Bisected commit-id:

Description Maxime Villard 2019-07-14 16:08:46 UTC
In vmx.c::vmx_get_msr(), there is some missing filtering on the PT (RTIT) MSRs. For example RTIT_CR3_MATCH:

	case MSR_IA32_RTIT_CR3_MATCH:
		if ((pt_mode != PT_MODE_HOST_GUEST) ||
			(vmx->pt_desc.guest.ctl & RTIT_CTL_TRACEEN) ||
			!intel_pt_validate_cap(vmx->pt_desc.caps,
						PT_CAP_cr3_filtering))
			return 1;
		vmx->pt_desc.guest.cr3_match = data;
		break;

Here, 'cr3_match' is set to the value given by the guest. Later, in pt_load_msr(), there is a blunt WRMSR:

	wrmsrl(MSR_IA32_RTIT_CR3_MATCH, ctx->cr3_match);

The Intel SDM indicates that

	"IA32_RTIT_CR3_MATCH[4:0] are reserved and must be 0; an attempt to
	 set those bits using WRMSR causes a #GP."

Given that KVM does not ensure that the aforementioned bits are zero, it seems that the guest could #GP the host.