use std::{ffi::CStr, process::ExitCode};
use data_encoding::HEXLOWER;
use nix::{
errno::Errno,
libc::{
getauxval, AT_BASE, AT_CLKTCK, AT_EGID, AT_ENTRY, AT_EUID, AT_FLAGS, AT_GID, AT_PAGESZ,
AT_PHDR, AT_PHENT, AT_PHNUM, AT_PLATFORM, AT_RANDOM, AT_SECURE, AT_UID,
},
};
use serde_json::json;
#[cfg(all(
not(coverage),
not(feature = "prof"),
not(target_os = "android"),
not(target_arch = "riscv64"),
target_page_size_4k,
target_pointer_width = "64"
))]
#[global_allocator]
static GLOBAL: hardened_malloc::HardenedMalloc = hardened_malloc::HardenedMalloc;
#[cfg(feature = "prof")]
#[global_allocator]
static GLOBAL: tcmalloc::TCMalloc = tcmalloc::TCMalloc;
syd::main! {
use lexopt::prelude::*;
syd::set_sigpipe_dfl()?;
let mut opt_secure = false;
let mut opt_random = false;
let mut parser = lexopt::Parser::from_env();
while let Some(arg) = parser.next()? {
match arg {
Short('h') => {
help();
return Ok(ExitCode::SUCCESS);
}
Short('r') => opt_random = true,
Short('s') => opt_secure = true,
Value(_) => {}
_ => return Err(arg.unexpected().into()),
}
}
if opt_secure && opt_random {
eprintln!("syd-aux: At most one of -r, -s must be given!");
return Err(Errno::EINVAL.into());
}
let at_secure = unsafe { getauxval(AT_SECURE) } != 0;
if opt_secure {
return Ok(if at_secure {
ExitCode::SUCCESS
} else {
ExitCode::FAILURE
});
}
let at_random = unsafe { getauxval(AT_RANDOM) };
let at_random =
HEXLOWER.encode(unsafe { std::slice::from_raw_parts(at_random as *const u8, 16) });
if opt_random {
println!("{at_random}");
return Ok(ExitCode::SUCCESS);
}
let at_uid = unsafe { getauxval(AT_UID) };
let at_euid = unsafe { getauxval(AT_EUID) };
let at_gid = unsafe { getauxval(AT_GID) };
let at_egid = unsafe { getauxval(AT_EGID) };
let at_base = unsafe { getauxval(AT_BASE) };
let at_clktck = unsafe { getauxval(AT_CLKTCK) };
let at_entry = unsafe { getauxval(AT_ENTRY) };
let at_flags = unsafe { getauxval(AT_FLAGS) };
let at_pagesz = unsafe { getauxval(AT_PAGESZ) };
let at_phdr = unsafe { getauxval(AT_PHDR) };
let at_phent = unsafe { getauxval(AT_PHENT) };
let at_phnum = unsafe { getauxval(AT_PHNUM) };
let at_platform = unsafe { getauxval(AT_PLATFORM) };
let at_platform = unsafe { CStr::from_ptr(at_platform as *const nix::libc::c_char) }
.to_string_lossy()
.into_owned();
#[expect(clippy::disallowed_methods)]
let aux = json!({
"uid": at_uid,
"euid": at_euid,
"gid": at_gid,
"egid": at_egid,
"base": at_base,
"clktck": at_clktck,
"entry": at_entry,
"flags": at_flags,
"pagesz": at_pagesz,
"phdr": at_phdr,
"phent": at_phent,
"phnum": at_phnum,
"secure": at_secure,
"random": at_random,
"platform": at_platform,
});
#[expect(clippy::disallowed_methods)]
let aux = serde_json::to_string_pretty(&aux).unwrap();
println!("{aux}");
Ok(ExitCode::SUCCESS)
}
fn help() {
println!("Usage: syd-aux [-hrs]");
println!("Print auxiliary vector information.");
println!("If -r is given print hexadecimal-encoded AT_RANDOM cookie.");
println!("If -s is given exit with success if AT_SECURE is set.");
}