Mercurial > crates > nonstick
diff src/libpam/question.rs @ 101:94b51fa4f797
Fix memory soundness issues:
- Ensure Questions are pinned in memory when sending them through PAM.
- Hold on to the PAM conversation struct after we build it.
(Linux-PAM is leninent about this and copies the pam_conv structure.)
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Tue, 24 Jun 2025 17:54:33 -0400 |
parents | b87100c5eed4 |
children |
line wrap: on
line diff
--- a/src/libpam/question.rs Tue Jun 24 17:08:01 2025 -0400 +++ b/src/libpam/question.rs Tue Jun 24 17:54:33 2025 -0400 @@ -11,6 +11,7 @@ use crate::Result; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::ffi::{c_void, CStr}; +use std::pin::Pin; use std::slice; /// Abstraction of a collection of questions to be sent in a PAM conversation. @@ -64,7 +65,7 @@ Self: Sized; /// Gets the pointer that is passed . - fn ptr(&self) -> *const *const Question; + fn ptr(self: Pin<&Self>) -> *const *const Question; /// Converts a pointer into a borrowed list of Questions. /// @@ -115,7 +116,7 @@ }) } - fn ptr(&self) -> *const *const Question { + fn ptr(self: Pin<&Self>) -> *const *const Question { &self.pointer as *const *const Question } @@ -131,10 +132,9 @@ #[derive(Debug)] #[repr(C)] pub struct LinuxPamQuestions { - #[allow(clippy::vec_box)] // we need to do this. + #[allow(clippy::vec_box)] // we need to box vec items. /// The place where the questions are. questions: Vec<Box<Question>>, - _marker: Immovable, } impl LinuxPamQuestions { @@ -155,11 +155,10 @@ .collect(); Ok(Self { questions: questions?, - _marker: Default::default(), }) } - fn ptr(&self) -> *const *const Question { + fn ptr(self: Pin<&Self>) -> *const *const Question { self.questions.as_ptr().cast() } @@ -246,7 +245,6 @@ Ok(Self { style: style.into(), data: Some(data), - _marker: Default::default(), }) } } @@ -328,15 +326,15 @@ use super::super::*; #[test] fn standard() { - let interrogation = <$typ>::new(&[ + let interrogation = Box::pin(<$typ>::new(&[ MaskedQAndA::new("hocus pocus").message(), QAndA::new("what").message(), QAndA::new("who").message(), InfoMsg::new("hey").message(), ErrorMsg::new("gasp").message(), ]) - .unwrap(); - let indirect = interrogation.ptr(); + .unwrap()); + let indirect = interrogation.as_ref().ptr(); let remade = unsafe { $typ::borrow_ptr(indirect, interrogation.len()) }; let messages: Vec<OwnedMessage> = remade @@ -364,11 +362,11 @@ #[test] #[cfg(feature = "linux-pam-extensions")] fn linux_extensions() { - let interrogation = <$typ>::new(&[ + let interrogation = Box::pin(<$typ>::new(&[ BinaryQAndA::new((&[5, 4, 3, 2, 1], 66)).message(), RadioQAndA::new("you must choose").message(), - ]).unwrap(); - let indirect = interrogation.ptr(); + ]).unwrap()); + let indirect = interrogation.as_ref().ptr(); let remade = unsafe { $typ::borrow_ptr(indirect, interrogation.len()) }; let messages: Vec<OwnedMessage> = remade