Skip to content

Commit

Permalink
Add a rustix::runtime:::random() function. (#953)
Browse files Browse the repository at this point in the history
This function returns the value of `AT_RANDOM`, for use by origin for
initializing the stack-smashing protection canary.
  • Loading branch information
sunfishcode authored Nov 29, 2023
1 parent d906002 commit 7242fdc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
23 changes: 22 additions & 1 deletion src/backend/linux_raw/param/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use linux_raw_sys::general::{
};
#[cfg(feature = "runtime")]
use linux_raw_sys::general::{
AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE, AT_UID,
AT_EGID, AT_ENTRY, AT_EUID, AT_GID, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE, AT_UID,
};

#[cfg(feature = "param")]
Expand Down Expand Up @@ -145,6 +145,19 @@ pub(crate) fn entry() -> usize {
entry
}

#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn random() -> *const [u8; 16] {
let mut random = RANDOM.load(Relaxed);

if random.is_null() {
init_auxv();
random = RANDOM.load(Relaxed);
}

random
}

static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
static HWCAP: AtomicUsize = AtomicUsize::new(0);
Expand All @@ -161,6 +174,8 @@ static PHENT: AtomicUsize = AtomicUsize::new(0);
static PHNUM: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "runtime")]
static ENTRY: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "runtime")]
static RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(null_mut());

#[cfg(feature = "alloc")]
fn pr_get_auxv() -> crate::io::Result<Vec<u8>> {
Expand Down Expand Up @@ -296,6 +311,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
let mut gid = None;
#[cfg(feature = "runtime")]
let mut egid = None;
#[cfg(feature = "runtime")]
let mut random = null_mut();

for Elf_auxv_t { a_type, a_val } in aux_iter {
match a_type as _ {
Expand Down Expand Up @@ -332,6 +349,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
AT_PHENT => phent = a_val as usize,
#[cfg(feature = "runtime")]
AT_ENTRY => entry = a_val as usize,
#[cfg(feature = "runtime")]
AT_RANDOM => random = check_raw_pointer::<[u8; 16]>(a_val as *mut _)?.as_ptr(),

AT_NULL => break,
_ => (),
Expand Down Expand Up @@ -365,6 +384,8 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
PHNUM.store(phnum, Relaxed);
#[cfg(feature = "runtime")]
ENTRY.store(entry, Relaxed);
#[cfg(feature = "runtime")]
RANDOM.store(random, Relaxed);

Some(())
}
Expand Down
12 changes: 11 additions & 1 deletion src/backend/linux_raw/param/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use linux_raw_sys::general::{
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
};
#[cfg(feature = "runtime")]
use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_SECURE};
use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE};

#[cfg(feature = "param")]
#[inline]
Expand Down Expand Up @@ -84,6 +84,12 @@ pub(crate) fn entry() -> usize {
unsafe { ENTRY.load(Ordering::Relaxed) }
}

#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn random() -> *const [u8; 16] {
unsafe { RANDOM.load(Ordering::Relaxed) }
}

static mut PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
static mut CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
static mut HWCAP: AtomicUsize = AtomicUsize::new(0);
Expand All @@ -103,6 +109,8 @@ static mut PHENT: AtomicUsize = AtomicUsize::new(0);
static mut PHNUM: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "runtime")]
static mut ENTRY: AtomicUsize = AtomicUsize::new(0);
#[cfg(feature = "runtime")]
static mut RANDOM: AtomicPtr<[u8; 16]> = AtomicPtr::new(NonNull::dangling().as_ptr());

/// When "use-explicitly-provided-auxv" is enabled, we export a function to be
/// called during initialization, and passed a pointer to the original
Expand Down Expand Up @@ -152,6 +160,8 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) {
AT_PHENT => PHENT.store(a_val as usize, Ordering::Relaxed),
#[cfg(feature = "runtime")]
AT_ENTRY => ENTRY.store(a_val as usize, Ordering::Relaxed),
#[cfg(feature = "runtime")]
AT_RANDOM => RANDOM.store(a_val.cast::<[u8; 16]>(), Ordering::Relaxed),

AT_NULL => break,
_ => (),
Expand Down
10 changes: 10 additions & 0 deletions src/backend/linux_raw/param/libc_auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const AT_PHNUM: c::c_ulong = 5;
#[cfg(feature = "runtime")]
const AT_ENTRY: c::c_ulong = 9;
const AT_HWCAP: c::c_ulong = 16;
#[cfg(feature = "runtime")]
const AT_RANDOM: c::c_ulong = 25;
const AT_HWCAP2: c::c_ulong = 26;
const AT_SECURE: c::c_ulong = 23;
const AT_EXECFN: c::c_ulong = 31;
Expand Down Expand Up @@ -68,6 +70,8 @@ fn test_abi() {
const_assert_eq!(self::AT_PHNUM, ::libc::AT_PHNUM);
#[cfg(feature = "runtime")]
const_assert_eq!(self::AT_ENTRY, ::libc::AT_ENTRY);
#[cfg(feature = "runtime")]
const_assert_eq!(self::AT_RANDOM, ::libc::AT_RANDOM);
}

#[cfg(feature = "param")]
Expand Down Expand Up @@ -163,3 +167,9 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
pub(crate) fn entry() -> usize {
unsafe { getauxval(AT_ENTRY) as usize }
}

#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn random() -> *const [u8; 16] {
unsafe { getauxval(AT_RANDOM) as *const [u8; 16] }
}
13 changes: 13 additions & 0 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,19 @@ pub fn entry() -> usize {
backend::param::auxv::entry()
}

/// `getauxval(AT_RANDOM)`—Returns the address of 16 pseudorandom bytes.
///
/// These bytes are for use by libc. For anything else, use the `rand` crate.
///
/// # References
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
#[inline]
pub fn random() -> *const [u8; 16] {
backend::param::auxv::random()
}

#[cfg(linux_raw)]
pub use backend::runtime::tls::StartupTlsInfo;

Expand Down

0 comments on commit 7242fdc

Please sign in to comment.