diff --git a/cryptovec/src/platform/unix.rs b/cryptovec/src/platform/unix.rs index 611a8bd6..745bb1e9 100644 --- a/cryptovec/src/platform/unix.rs +++ b/cryptovec/src/platform/unix.rs @@ -1,3 +1,5 @@ +use std::ffi::CStr; + use libc::c_void; /// Unlock memory on drop for Unix-based systems. @@ -5,7 +7,7 @@ pub fn munlock(ptr: *const u8, len: usize) { unsafe { #[allow(clippy::panic)] if libc::munlock(ptr as *const c_void, len) != 0 { - panic!("Failed to unlock memory"); + panic_libc_error("Failed to unlock memory"); } } } @@ -14,7 +16,7 @@ pub fn mlock(ptr: *const u8, len: usize) { unsafe { #[allow(clippy::panic)] if libc::mlock(ptr as *const c_void, len) != 0 { - panic!("Failed to lock memory"); + panic_libc_error("Failed to lock memory"); } } } @@ -24,3 +26,20 @@ pub fn memset(ptr: *mut u8, value: i32, size: usize) { libc::memset(ptr as *mut c_void, value, size); } } + +unsafe fn panic_libc_error(msg: &str) { + let errno = *libc::__errno_location(); + const ERRMAXLEN: usize = 255; + let mut errdesc = [0u8; ERRMAXLEN]; + let errdesc = if libc::strerror_r(errno, errdesc.as_mut_ptr() as _, ERRMAXLEN) == 0 { + CStr::from_bytes_until_nul(&errdesc) + .ok() + .and_then(|msg| msg.to_str().ok()) + .unwrap_or("Invalid error description") + } else { + "Invalid error" + }; + // Note: if you get 'Cannot allocate memory (0xc)' here, + // check if your RLIMIT_MEMLOCK (`ulimit -l`) is configured low! + panic!("{}: {} (0x{:x})", msg, errdesc, errno); +}