Shouldn't one always check a pointer is not null and aligned before dereferencing

⚓ Rust    📅 2025-08-31    👤 surdeus    👁️ 2      

surdeus

I realize this may be an "extreme" example, but nix::errno::Errno::last_raw "blindly" dereferences the pointer without first ensuring it is not null and aligned:

    pub fn last_raw() -> i32 {
        unsafe { *errno_location() }
    }

While I realize something would seem to be very messed up for __errno_location (and other platform-equivalent functions) to return null or a non-aligned pointer, wouldn't it still be better to verify the conditions are true and then panic if not?

For example, my code looks something like this:

    pub fn last() -> Self {
        #[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
        // SAFETY:
        // Supposed to be a thread-local variable, but there is no
        // "check" to ensure this.
        let ptr = unsafe { c::__errno() };
        #[cfg(any(target_os = "freebsd", target_vendor = "apple"))]
        // SAFETY:
        // Supposed to be a thread-local variable, but there is no
        // "check" to ensure this.
        let ptr = unsafe { c::__error() };
        #[cfg(any(target_os = "dragonfly", target_os = "linux"))]
        // SAFETY:
        // Supposed to be a thread-local variable, but there is no
        // "check" to ensure this.
        let ptr = unsafe { c::__errno_location() };
        assert!(
            !ptr.is_null() && ptr.is_aligned(),
            "libc errno returned a pointer that was either null or not aligned"
        );
        // SAFETY:
        // Verified above that `ptr` is not null and aligned.
        Self::from_raw(unsafe { *ptr })
    }

I realize one can't verify everything about the FFI call (e.g., one can only assume __errno_location is thread-local), but I don't think that means one should not check for things that it can. Is this a case of being too safe on my part?

4 posts - 3 participants

Read full topic

🏷️ Rust_feed