VMCS auditor
This commit is contained in:
113
nel_os_kernel/src/vmm/x86_64/intel/auditor/controls.rs
Normal file
113
nel_os_kernel/src/vmm/x86_64/intel/auditor/controls.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use x86::{msr, vmx::vmcs};
|
||||||
|
|
||||||
|
use crate::vmm::x86_64::{
|
||||||
|
common::read_msr,
|
||||||
|
intel::{self, vmread},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn check_vmcs_control_fields() -> Result<(), &'static str> {
|
||||||
|
let msr_ia32_vmx_basic = read_msr(msr::IA32_VMX_BASIC);
|
||||||
|
let vmx_true_ctrl = msr_ia32_vmx_basic & (1 << 55) != 0;
|
||||||
|
|
||||||
|
check_pin_based_exec_ctrl(vmx_true_ctrl)?;
|
||||||
|
check_primary_proc_based_exec_ctrl(vmx_true_ctrl)?;
|
||||||
|
|
||||||
|
if intel::vmcs::controls::PrimaryProcessorBasedVmExecutionControls::read()?
|
||||||
|
.activate_secondary_controls()
|
||||||
|
{
|
||||||
|
check_secondary_proc_based_exec_ctrl(vmx_true_ctrl)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_pin_based_exec_ctrl(vmx_true_ctrl: bool) -> Result<(), &'static str> {
|
||||||
|
let msr_vmx_pin_based_exec_ctrl = if vmx_true_ctrl {
|
||||||
|
read_msr(msr::IA32_VMX_TRUE_PINBASED_CTLS)
|
||||||
|
} else {
|
||||||
|
read_msr(msr::IA32_VMX_PINBASED_CTLS)
|
||||||
|
};
|
||||||
|
|
||||||
|
let vmcs_pin_based_exec_ctrl = vmread(vmcs::control::PINBASED_EXEC_CONTROLS)?;
|
||||||
|
let msr_vmx_pin_based_exec_ctrl_low = (msr_vmx_pin_based_exec_ctrl & 0xFFFFFFFF) as u32;
|
||||||
|
let msr_vmx_pin_based_exec_ctrl_high = (msr_vmx_pin_based_exec_ctrl >> 32) as u32;
|
||||||
|
|
||||||
|
if !(vmcs_pin_based_exec_ctrl & 0xFFFFFFFF) as u32 & msr_vmx_pin_based_exec_ctrl_low != 0 {
|
||||||
|
return Err(
|
||||||
|
"VMCS Pin-based execution controls field: IA32_VMX_PINBASED_CTRLS low bits not set",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (vmcs_pin_based_exec_ctrl >> 32) as u32 & !msr_vmx_pin_based_exec_ctrl_high != 0 {
|
||||||
|
return Err(
|
||||||
|
"VMCS Pin-based execution controls field: IA32_VMX_PINBASED_CTRLS high bits not zero",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_primary_proc_based_exec_ctrl(vmx_true_ctrl: bool) -> Result<(), &'static str> {
|
||||||
|
let msr_vmx_primary_proc_based_exec_ctrl = if vmx_true_ctrl {
|
||||||
|
read_msr(msr::IA32_VMX_TRUE_PROCBASED_CTLS)
|
||||||
|
} else {
|
||||||
|
read_msr(msr::IA32_VMX_PROCBASED_CTLS)
|
||||||
|
};
|
||||||
|
|
||||||
|
let vmcs_primary_proc_based_exec_ctrl = vmread(vmcs::control::PRIMARY_PROCBASED_EXEC_CONTROLS)?;
|
||||||
|
let msr_vmx_primary_proc_based_exec_ctrl_low =
|
||||||
|
(msr_vmx_primary_proc_based_exec_ctrl & 0xFFFFFFFF) as u32;
|
||||||
|
let msr_vmx_primary_proc_based_exec_ctrl_high =
|
||||||
|
(msr_vmx_primary_proc_based_exec_ctrl >> 32) as u32;
|
||||||
|
|
||||||
|
if !(vmcs_primary_proc_based_exec_ctrl & 0xFFFFFFFF) as u32
|
||||||
|
& msr_vmx_primary_proc_based_exec_ctrl_low
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
|
return Err(
|
||||||
|
"VMCS Primary processor-based execution controls field: IA32_VMX_PROCBASED_CTRLS low bits not set",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (vmcs_primary_proc_based_exec_ctrl >> 32) as u32 & !msr_vmx_primary_proc_based_exec_ctrl_high
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
|
return Err(
|
||||||
|
"VMCS Primary processor-based execution controls field: IA32_VMX_PROCBASED_CTRLS high bits not zero",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_secondary_proc_based_exec_ctrl(vmx_true_ctrl: bool) -> Result<(), &'static str> {
|
||||||
|
let msr_vmx_secondary_proc_based_exec_ctrl = if vmx_true_ctrl {
|
||||||
|
read_msr(msr::IA32_VMX_PROCBASED_CTLS2)
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
let vmcs_secondary_proc_based_exec_ctrl =
|
||||||
|
vmread(vmcs::control::SECONDARY_PROCBASED_EXEC_CONTROLS)?;
|
||||||
|
let msr_vmx_secondary_proc_based_exec_ctrl_low =
|
||||||
|
(msr_vmx_secondary_proc_based_exec_ctrl & 0xFFFFFFFF) as u32;
|
||||||
|
let msr_vmx_secondary_proc_based_exec_ctrl_high =
|
||||||
|
(msr_vmx_secondary_proc_based_exec_ctrl >> 32) as u32;
|
||||||
|
|
||||||
|
if !(vmcs_secondary_proc_based_exec_ctrl & 0xFFFFFFFF) as u32
|
||||||
|
& msr_vmx_secondary_proc_based_exec_ctrl_low
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
|
return Err(
|
||||||
|
"VMCS Secondary processor-based execution controls field: IA32_VMX_PROCBASED_CTRLS2 low bits not set",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (vmcs_secondary_proc_based_exec_ctrl >> 32) as u32
|
||||||
|
& !msr_vmx_secondary_proc_based_exec_ctrl_high
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
|
return Err(
|
||||||
|
"VMCS Secondary processor-based execution controls field: IA32_VMX_PROCBASED_CTRLS2 high bits not zero",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
1
nel_os_kernel/src/vmm/x86_64/intel/auditor/mod.rs
Normal file
1
nel_os_kernel/src/vmm/x86_64/intel/auditor/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod controls;
|
@ -1,4 +1,5 @@
|
|||||||
pub mod asm;
|
pub mod asm;
|
||||||
|
mod auditor;
|
||||||
mod controls;
|
mod controls;
|
||||||
mod cpuid;
|
mod cpuid;
|
||||||
mod ept;
|
mod ept;
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
x86_64::{
|
x86_64::{
|
||||||
common::{self, read_msr},
|
common::{self, read_msr},
|
||||||
intel::{
|
intel::{
|
||||||
controls, cpuid, ept,
|
auditor, controls, cpuid, ept,
|
||||||
msr::{self, ShadowMsr},
|
msr::{self, ShadowMsr},
|
||||||
register::GuestRegisters,
|
register::GuestRegisters,
|
||||||
vmcs::{
|
vmcs::{
|
||||||
@ -123,6 +123,8 @@ impl IntelVCpu {
|
|||||||
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
||||||
msr::update_msrs(self).unwrap();
|
msr::update_msrs(self).unwrap();
|
||||||
|
|
||||||
|
auditor::controls::check_vmcs_control_fields().unwrap();
|
||||||
|
|
||||||
let success = {
|
let success = {
|
||||||
let result: u16;
|
let result: u16;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
Reference in New Issue
Block a user