From eb362c5c7751f107fa6f76449d41efdec2bae20d Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Fri, 14 Jul 2023 13:59:24 +0100 Subject: [PATCH] libnoaslr support for netbsd (#1366) --- utils/noaslr/libnoaslr/Cargo.toml | 2 +- utils/noaslr/libnoaslr/src/lib.rs | 105 ++++++++++++++++++++++++++++-- utils/noaslr/noaslr/src/main.rs | 4 +- 3 files changed, 102 insertions(+), 9 deletions(-) diff --git a/utils/noaslr/libnoaslr/Cargo.toml b/utils/noaslr/libnoaslr/Cargo.toml index 73a11e954b..712c0d4a85 100644 --- a/utils/noaslr/libnoaslr/Cargo.toml +++ b/utils/noaslr/libnoaslr/Cargo.toml @@ -15,5 +15,5 @@ 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] +[target.'cfg(any(target_os = "freebsd", target_os = "netbsd"))'.dependencies] libc = "0.2" diff --git a/utils/noaslr/libnoaslr/src/lib.rs b/utils/noaslr/libnoaslr/src/lib.rs index f78fda0d05..2517166b4c 100644 --- a/utils/noaslr/libnoaslr/src/lib.rs +++ b/utils/noaslr/libnoaslr/src/lib.rs @@ -1,8 +1,3 @@ -#[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}, @@ -13,6 +8,12 @@ use { }, std::{ffi::CString, fs::File, io::Read}, }; +#[cfg(not(any(target_os = "linux", target_os = "android")))] +use { + anyhow::{anyhow, Result}, + ctor::ctor, + std::ffi::CString, +}; #[cfg(any(target_os = "linux", target_os = "android"))] fn read_null_lines(path: &str) -> Result> { @@ -102,7 +103,99 @@ fn libnoaslr() -> Result<()> { Ok(()) } -#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))] +#[cfg(target_os = "netbsd")] +fn libnoaslr() -> Result<()> { + unsafe { + let mut aslr: i32 = 0; + let mut s = std::mem::size_of::(); + let nm = CString::new("security.pax.aslr.enabled") + .map_err(|e| anyhow!("Failed to create sysctl oid: {e:}")) + .unwrap(); + if libc::sysctlbyname( + nm.as_ptr(), + &mut aslr as *mut i32 as _, + &mut s, + std::ptr::null(), + 0, + ) < 0 + { + return Err(anyhow!("Failed to get aslr status")); + } + + if aslr > 0 { + return Err(anyhow!( + "Please disable aslr with sysctl -w security.pax.aslr.enabled=0 as privileged user" + )); + } + let mib = &mut [ + libc::CTL_KERN, + libc::KERN_PROC_ARGS, + libc::getpid(), + libc::KERN_PROC_ARGV, + ]; + let miblen = mib.len() as u32; + s = 0; + if libc::sysctl( + mib.as_mut_ptr(), + miblen, + std::ptr::null_mut(), + &mut s, + std::ptr::null_mut(), + 0, + ) < 0 + { + return Err(anyhow!("Failed to get argv buffer")); + } + let mut pargs: Vec = Vec::with_capacity(s); + 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")); + } + mib[3] = libc::KERN_PROC_ENV; + s = 0; + if libc::sysctl( + mib.as_mut_ptr(), + miblen, + std::ptr::null_mut(), + &mut s, + std::ptr::null_mut(), + 0, + ) < 0 + { + return Err(anyhow!("Failed to get env buffer")); + } + let mut penv: Vec = Vec::with_capacity(s); + if libc::sysctl( + mib.as_mut_ptr(), + miblen, + penv.as_mut_ptr() as _, + &mut s, + std::ptr::null_mut(), + 0, + ) < 0 + { + return Err(anyhow!("Failed to get argv")); + } + let args = pargs.as_mut_ptr(); + let env = penv.as_mut_ptr() as _; + libc::execvpe(args.add(0) as _, args as _, env); + } + Ok(()) +} + +#[cfg(any( + target_os = "linux", + target_os = "android", + target_os = "freebsd", + target_os = "netbsd" +))] #[ctor] fn init() { libnoaslr().unwrap(); diff --git a/utils/noaslr/noaslr/src/main.rs b/utils/noaslr/noaslr/src/main.rs index fa4e3afde0..f2e34c34a5 100644 --- a/utils/noaslr/noaslr/src/main.rs +++ b/utils/noaslr/noaslr/src/main.rs @@ -8,7 +8,6 @@ use { nix::unistd::execvp, std::ffi::CString, }; - #[cfg(any(target_os = "linux", target_os = "android"))] use { crate::args::Args, @@ -60,7 +59,8 @@ fn disable_aslr() -> Result<()> { std::ptr::null_mut(), &disable as *const i32 as _, s, - ) < 0 { + ) < 0 + { return Err(anyhow!("Failed to disable aslr")); } }