use crate::error::private::ResultExt;
#[cfg(target_os = "macos")]
unsafe fn ptrace(request: i32, pid: libc::pid_t, addr: *mut u8, data: i32) -> i32 {
unsafe { libc::ptrace(request, pid, addr.cast::<libc::c_char>(), data) }
}
#[cfg(target_os = "linux")]
pub fn set_process_nontraceable() -> anyhow::Result<()> {
rustix::process::set_dumpable_behavior(rustix::process::DumpableBehavior::NotDumpable)
.map_anyhow()
}
#[cfg(target_os = "freebsd")]
pub fn set_process_nontraceable() -> anyhow::Result<()> {
rustix::process::set_dumpable_behavior(
None,
rustix::process::DumpableBehavior::NotDumpableExecPreserved,
)
.map_anyhow()
}
#[cfg(target_os = "macos")]
pub fn set_process_nontraceable() -> anyhow::Result<()> {
let res: i32 = unsafe { ptrace(libc::PT_DENY_ATTACH, 0, core::ptr::null_mut(), 0) };
if res == 0 {
Ok(())
} else {
Err(crate::error::SysErr::create_anyhow())
}
}
#[cfg(target_os = "freebsd")]
pub fn is_tracer_present() -> anyhow::Result<Option<rustix::process::Pid>> {
match rustix::process::trace_status(None).map_anyhow()? {
rustix::process::TracingStatus::BeingTraced(pid) => Ok(Some(pid)),
_ => Ok(None),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
#[test]
fn test_process_nondumpable() {
assert!(set_process_nontraceable().is_ok());
}
}