Skip to content

Commit

Permalink
use cpuid instead of reading /proc/cpuinfo
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcondiro committed Aug 20, 2024
1 parent 707ca1c commit 30489e9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
1 change: 1 addition & 0 deletions libafl_qemu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ getset = "0.1"
bitflags = "2.6"
perf-event-open-sys = "4" # Uses Linux 5.19.4 headers, consider forking if we need to bump
caps = "0.5" # TODO: Mark deps used only in systemmode as optional (requires fixing linux_build.rs)
raw-cpuid = "11"
libipt = {git = "https://github.com/Marcondiro/libipt-rs"} # v2 is not on crates.io
# Document all features of this crate (for `cargo doc`)
document-features = { version = "0.2", optional = true }
Expand Down
38 changes: 27 additions & 11 deletions libafl_qemu/src/qemu/systemmode/intel_pt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ use std::{
use bitflags::bitflags;
use caps::{CapSet, Capability};
use libafl::Error;
use libipt::{block::BlockDecoder, ConfigBuilder, Image};
use libipt::{block::BlockDecoder, ConfigBuilder, Cpu, Image};
use num_enum::TryFromPrimitive;
use perf_event_open_sys::{
bindings::{perf_event_attr, perf_event_mmap_page, PERF_FLAG_FD_CLOEXEC},
ioctls::{DISABLE, ENABLE, SET_FILTER},
perf_event_open,
};
use raw_cpuid::CpuId;

const PAGE_SIZE: usize = 4096;
const PERF_BUFFER_SIZE: usize = (1 + (1 << 7)) * PAGE_SIZE;
const PERF_AUX_BUFFER_SIZE: usize = 64 * 1024 * 1024;
const CPU_INFO_PATH: &str = "/proc/cpuinfo";
const PT_EVENT_PATH: &str = "/sys/bus/event_source/devices/intel_pt";

#[derive(TryFromPrimitive, Debug)]
Expand Down Expand Up @@ -203,14 +203,16 @@ impl IntelPT {
// TODO config.cpu = <cpu identifier>; ?
// TODO handle decoding failures with config.decode.callback = <decode function>; config.decode.context = <decode context>;
// TODO remove unwrap()
let config = ConfigBuilder::new(unsafe { slice::from_raw_parts_mut(data, len) })
.unwrap()
.finish();
let mut decoder = BlockDecoder::new(&config).unwrap();
let mut config =
ConfigBuilder::new(unsafe { slice::from_raw_parts_mut(data, len) }).unwrap();
if let Some(cpu) = current_cpu() {
config.cpu(cpu);
}
let mut decoder = BlockDecoder::new(&config.finish()).unwrap();
decoder.set_image(Some(image)).expect("Failed to set image");

// TODO rewrite decently
// TODO consider dropping libipt-rs and using sys, or bingen ourselves
// TODO consider dropping libipt-rs and using sys, or bindgen ourselves
let mut status;
loop {
status = match decoder.sync_forward() {
Expand Down Expand Up @@ -285,15 +287,21 @@ impl IntelPT {
reasons.push("Only x86_64 is supported.".to_owned());
}

if let Ok(cpu_info) = fs::read_to_string(CPU_INFO_PATH) {
if !cpu_info.contains("GenuineIntel") && !cpu_info.contains("GenuineIotel") {
let cpuid = CpuId::new();
if let Some(vendor) = cpuid.get_vendor_info() {
if vendor.as_str() != "GenuineIntel" && vendor.as_str() != "GenuineIotel" {
reasons.push("Only Intel CPUs are supported.".to_owned());
}
if !cpu_info.contains("intel_pt") {
} else {
reasons.push("Failed to read CPU vendor".to_owned());
}

if let Some(ef) = cpuid.get_extended_feature_info() {
if !ef.has_processor_trace() {
reasons.push("Intel PT is not supported by the CPU.".to_owned());
}
} else {
reasons.push("Failed to read CPU info".to_owned());
reasons.push("Failed to read CPU Extended Features".to_owned());
}

if let Err(e) = intel_pt_perf_type() {
Expand Down Expand Up @@ -462,6 +470,14 @@ pub fn smp_rmb() {
}
}

#[inline]
pub fn current_cpu() -> Option<Cpu> {
let cpuid = CpuId::new();
cpuid
.get_feature_info()
.map(|fi| Cpu::intel(fi.family_id() as u16, fi.model_id(), fi.stepping_id()))
}

#[cfg(test)]
mod test {
use std::{env, fs::OpenOptions, process};
Expand Down

0 comments on commit 30489e9

Please sign in to comment.