diff --git a/Cargo.toml b/Cargo.toml index 7ef33c0..ea88e34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ # General info [package] name = "whitebeam" -version = "0.0.7" +version = "0.0.8" authors = ["noproto"] edition = "2018" @@ -19,7 +19,6 @@ required-features = ["binaries"] # Cross-platform dependencies [dependencies] - serde = { version = "1.0.99", features = ["derive"] } serde_json = { version = "1.0.40" } hex = { version = "0.3.2", optional = true } diff --git a/Makefile b/Makefile index a871737..cc4309e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ all: library binary library: @echo "Building library" - cargo build --lib --release --features=libraries + cargo +nightly build --lib --release --features=libraries strip $(shell pwd)/target/release/libwhitebeam.so @echo "Completed. Size:" @du -h $(shell pwd)/target/release/libwhitebeam.so | cut -f1 diff --git a/src/lib.rs b/src/lib.rs index ebdf7ed..46b559f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ +#![feature(c_variadic)] #[macro_use] pub mod library; diff --git a/src/library/platforms/linux/hooks/execle.rs b/src/library/platforms/linux/hooks/execle.rs index 78e4ca8..f6758ac 100644 --- a/src/library/platforms/linux/hooks/execle.rs +++ b/src/library/platforms/linux/hooks/execle.rs @@ -3,22 +3,32 @@ use crate::library::platforms::linux; use crate::library::common::whitelist; use crate::library::common::event; -/* - int execle(const char *path, const char *arg, ... - /*, (char *) NULL, char * const envp[] */); -*/ -hook! { - unsafe fn hooked_execle(path: *const c_char, arg: *const c_char, null: *const c_char, envp: *const *const c_char) -> c_int => execle { - let (program, env) = linux::transform_parameters(path, envp, -1); - let (hexdigest, uid) = linux::get_hash_and_uid(&program); - // Permit/deny execution - if whitelist::is_whitelisted(&program, &env, &hexdigest) { - event::send_exec_event(uid, &program, &hexdigest, true); - real!(hooked_execle)(path, arg, null, envp) - } else { - event::send_exec_event(uid, &program, &hexdigest, false); - *linux::errno_location() = libc::EACCES; - return -1 - } +#[no_mangle] +pub unsafe extern "C" fn execle(path: *const c_char, mut args: ...) -> c_int { + // Populate argv + let mut arg_vec: Vec<*const c_char> = Vec::new(); + let mut next_argv: isize = args.arg(); + let mut ptr_to_next_argv = next_argv as *const c_char; + while !(ptr_to_next_argv).is_null() { + arg_vec.push(ptr_to_next_argv); + next_argv = args.arg(); + ptr_to_next_argv = next_argv as *const c_char; + } + arg_vec.push(std::ptr::null()); + let argv: *const *const c_char = (&arg_vec).as_ptr() as *const *const c_char; + + // Populate envp + let envp_arg: isize = args.arg(); + let envp = envp_arg as *const *const c_char; + + // Call execve + static mut REAL: *const u8 = 0 as *const u8; + static mut ONCE: ::std::sync::Once = ::std::sync::Once::new(); + unsafe { + ONCE.call_once(|| { + REAL = crate::library::platforms::linux::hook::dlsym_next("execve\u{0}"); + }); } + let execve: unsafe extern "C" fn(path: *const c_char, argv: *const *const c_char, envp: *const *const c_char) -> c_int = unsafe { std::mem::transmute(REAL) }; + execve(path, argv, std::ptr::null()) } diff --git a/src/library/platforms/linux/hooks/mod.rs b/src/library/platforms/linux/hooks/mod.rs index 248a8ff..ec4c92a 100644 --- a/src/library/platforms/linux/hooks/mod.rs +++ b/src/library/platforms/linux/hooks/mod.rs @@ -10,7 +10,6 @@ exec hooks: Required +--------+-------------------------------------------------------------------------------------+ */ -// TODO: Limited support for variadic functions? (l) mod execl; mod execle; mod execlp; diff --git a/src/library/platforms/linux/mod.rs b/src/library/platforms/linux/mod.rs index a7c91d2..b06b893 100644 --- a/src/library/platforms/linux/mod.rs +++ b/src/library/platforms/linux/mod.rs @@ -52,8 +52,6 @@ unsafe fn transform_parameters(path: *const c_char, envp: *const *const c_char, // Program let program = if !(path.is_null()) { - // TODO: Segfaults execle when running /sbin/ifup -a --read-environment - // Why: path isn't a char pointer, it is the c_char let program_c_str: &CStr = CStr::from_ptr(path); let program_str_slice: &str = program_c_str.to_str().unwrap(); program_str_slice.to_owned()