f8175c8c69f80dd21609ffe92b417e942f074d49 / aldermon/src/bin/aldermon-msr.rs · 1845 bytes · raw
//! aldermon-msr — minimal setcap'd helper for VID reads.
//!
//! The kernel gates /dev/cpu/N/msr twice: file mode (0600 root:root;
//! CAP_SYS_RAWIO does NOT override DAC) AND msr_open()'s capable check —
//! so access needs BOTH a 0440 adm node (udev rule) AND the capability,
//! which file permissions can never grant. This helper is the only binary
//! that ever holds the capability: it reads exactly one hard-coded MSR
//! (IA32_PERF_STATUS 0x198), read-only, and prints one line per CPU.
//! Everything else — the app, its deps, its config writes — stays unprivileged.
//!
//! usage: aldermon-msr CPU [CPU...] -> "CPU 0x<hex>" per cpu, "CPU -" on miss
use std::io::{Read, Seek, Write};
const PERF_STATUS: u64 = 0x198;
const CPU_MAX: u32 = 4096;
fn read_perf_status(cpu: u32) -> Option<u64> {
let path = format!("/dev/cpu/{cpu}/msr");
let mut f = std::fs::File::open(path).ok()?;
f.seek(std::io::SeekFrom::Start(PERF_STATUS)).ok()?;
let mut buf = [0u8; 8];
f.read_exact(&mut buf).ok()?;
Some(u64::from_le_bytes(buf))
}
fn main() {
let mut cpus = Vec::new();
for arg in std::env::args().skip(1) {
match arg.parse::<u32>() {
Ok(c) if c <= CPU_MAX => cpus.push(c),
_ => {
eprintln!("usage: aldermon-msr CPU [CPU...]");
std::process::exit(2);
}
}
}
if cpus.is_empty() {
eprintln!("usage: aldermon-msr CPU [CPU...]");
std::process::exit(2);
}
let out = std::io::stdout();
let mut out = out.lock();
for cpu in cpus {
let line = match read_perf_status(cpu) {
Some(v) => format!("{cpu} {v:#x}\n"),
None => format!("{cpu} -\n"),
};
if out.write_all(line.as_bytes()).is_err() {
std::process::exit(1);
}
}
}