From ff3fd6af7f888ec9df48795bab1be157aa1b6b23 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 5 Feb 2024 10:13:48 +0000 Subject: [PATCH] std::thread update freensd stack guard handling. up to now, it had been assumed the stack guard setting default is not touched in the field but some user might just want to disable it or increase it. checking it once at runtime should be enough. --- library/std/src/sys/pal/unix/thread.rs | 39 ++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 7e4a01a5ecd33..312d1c28803d9 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -847,11 +847,40 @@ pub mod guard { let stackptr = get_stack_start_aligned()?; let guardaddr = stackptr.addr(); // Technically the number of guard pages is tunable and controlled - // by the security.bsd.stack_guard_page sysctl, but there are - // few reasons to change it from the default. The default value has - // been 1 ever since FreeBSD 11.1 and 10.4. - const GUARD_PAGES: usize = 1; - let guard = guardaddr..guardaddr + GUARD_PAGES * page_size; + // by the security.bsd.stack_guard_page sysctl. + // By default it is 1, checking once is enough since it is + // a boot time config value. + static LOCK: crate::sync::OnceLock = crate::sync::OnceLock::new(); + let guard = guardaddr + ..guardaddr + + *LOCK.get_or_init(|| { + extern "C" { + pub fn sysctlbyname( + oid: *const libc::c_char, + ov: *mut libc::c_void, + osize: *mut libc::size_t, + nv: *const libc::c_void, + nsize: libc::size_t, + ) -> libc::c_int; + } + let mut guard: usize = 0; + let mut size = crate::mem::size_of_val(&guard); + let oid = crate::ffi::CStr::from_bytes_with_nul( + b"security.bsd.stack_guard_page\0", + ) + .unwrap(); + let res = sysctlbyname( + oid.as_ptr(), + &mut guard as *mut _ as *mut _, + &mut size as *mut _ as *mut _, + crate::ptr::null_mut(), + 0, + ); + if res == 0 { + return guard; + } + 1 + }) * page_size; Some(guard) } else if cfg!(target_os = "openbsd") { // OpenBSD stack already includes a guard page, and stack is