Mercurial > crates > nonstick
diff src/libpam/question.rs @ 93:efc2b56c8928
Remove undefined behavior per MIRI.
This replaces a bunch of raw pointers with NonNull and removes all the
undefined behavior that we can find with MIRI.
We also remove the `SecureString` dependency (since it doesn't work with MIRI,
and because it's not really necessary).
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 23 Jun 2025 13:02:58 -0400 |
parents | dd3e9c4bcde3 |
children | b87100c5eed4 |
line wrap: on
line diff
--- a/src/libpam/question.rs Sun Jun 22 19:29:32 2025 -0400 +++ b/src/libpam/question.rs Mon Jun 23 13:02:58 2025 -0400 @@ -11,6 +11,7 @@ use crate::Result; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::ffi::{c_void, CStr}; +use std::ptr::NonNull; use std::{ptr, slice}; /// Abstraction of a collection of questions to be sent in a PAM conversation. @@ -214,10 +215,9 @@ /// Gets this message's data pointer as borrowed binary data. unsafe fn binary_data(&self) -> (&[u8], u8) { - self.data - .cast::<CBinaryData>() - .as_ref() - .map(Into::into) + NonNull::new(self.data) + .map(|nn| nn.cast()) + .map(|ptr| CBinaryData::data(ptr)) .unwrap_or_default() } } @@ -227,7 +227,7 @@ fn try_from(msg: &Message) -> Result<Self> { let alloc = |style, text| Ok((style, memory::malloc_str(text)?.cast())); // We will only allocate heap data if we have a valid input. - let (style, data): (_, *mut c_void) = match *msg { + let (style, data): (_, NonNull<c_void>) = match *msg { Message::MaskedPrompt(p) => alloc(Style::PromptEchoOff, p.question()), Message::Prompt(p) => alloc(Style::PromptEchoOn, p.question()), Message::Error(p) => alloc(Style::ErrorMsg, p.question()), @@ -244,7 +244,7 @@ }?; Ok(Self { style: style.into(), - data, + data: data.as_ptr(), _marker: Default::default(), }) } @@ -261,8 +261,8 @@ match style { #[cfg(feature = "linux-pam-extensions")] Style::BinaryPrompt => { - if let Some(d) = self.data.cast::<CBinaryData>().as_mut() { - d.zero_contents() + if let Some(d) = NonNull::new(self.data) { + CBinaryData::zero_contents(d.cast()) } } #[cfg(feature = "linux-pam-extensions")] @@ -367,7 +367,7 @@ let indirect = interrogation.ptr(); let remade = unsafe { $typ::borrow_ptr(indirect, interrogation.len()) }; - let messages: Vec<OwnedMessage> = unsafe { remade } + let messages: Vec<OwnedMessage> = remade .map(TryInto::try_into) .collect::<Result<_>>() .unwrap();