diff --git a/utils/noaslr/libnoaslr/Cargo.toml b/utils/noaslr/libnoaslr/Cargo.toml index b2bf2f022a..73a11e954b 100644 --- a/utils/noaslr/libnoaslr/Cargo.toml +++ b/utils/noaslr/libnoaslr/Cargo.toml @@ -14,3 +14,6 @@ crate-type = ["dylib"] anyhow = { version = "1.0.71", default-features = false } ctor = { version = "0.2.2", default-features = false } nix = { version = "0.26.2", default-features = false, features = ["process", "personality"] } + +[target.'cfg(target_os = "freebsd")'.dependencies] +libc = "0.2" diff --git a/utils/noaslr/libnoaslr/src/lib.rs b/utils/noaslr/libnoaslr/src/lib.rs index 0605564cdd..f78fda0d05 100644 --- a/utils/noaslr/libnoaslr/src/lib.rs +++ b/utils/noaslr/libnoaslr/src/lib.rs @@ -1,3 +1,8 @@ +#[cfg(not(any(target_os = "linux", target_os = "android")))] +use { + anyhow::{anyhow, Result}, + ctor::ctor, +}; #[cfg(any(target_os = "linux", target_os = "android"))] use { anyhow::{anyhow, Result}, @@ -39,7 +44,65 @@ fn libnoaslr() -> Result<()> { Ok(()) } -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(target_os = "freebsd")] +fn libnoaslr() -> Result<()> { + extern "C" { + fn exect( + c: *const libc::c_char, + args: *const *const libc::c_char, + env: *const *const libc::c_char, + ) -> libc::c_int; + } + let mut status = libc::PROC_ASLR_FORCE_DISABLE; + let mut pargs: Vec = vec![0; 256]; + let mut penv: Vec = vec![0; 256]; + let mut s = pargs.len(); + let mib = &mut [libc::CTL_KERN, libc::KERN_PROC, libc::KERN_PROC_ARGS, -1]; + let miblen = mib.len() as u32; + unsafe { + if libc::procctl( + libc::P_PID, + 0, + libc::PROC_ASLR_CTL, + &mut status as *mut i32 as *mut libc::c_void, + ) < 0 + { + return Err(anyhow!("Failed to set aslr control")); + } + if libc::sysctl( + mib.as_mut_ptr(), + miblen, + pargs.as_mut_ptr() as _, + &mut s, + std::ptr::null_mut(), + 0, + ) < 0 + { + return Err(anyhow!("Failed to get argv")); + } + pargs.set_len(s - 1); + let args = pargs.as_mut_ptr(); + let mut env = std::ptr::null_mut(); + mib[2] = libc::KERN_PROC_ENV; + s = penv.len(); + if libc::sysctl( + mib.as_mut_ptr(), + miblen, + penv.as_mut_ptr() as _, + &mut s, + std::ptr::null_mut(), + 0, + ) == 0 + { + penv.set_len(s - 1); + env = penv.as_mut_ptr() as _; + } + exect(args.add(0) as _, args as _, env); + } + Ok(()) +} + +#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] #[ctor] fn init() { libnoaslr().unwrap();