Mercurial > crates > nonstick
comparison src/libpam/conversation.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 | 3f11b8d30f63 |
| children | 80c07e5ab22f |
comparison
equal
deleted
inserted
replaced
| 100:3f11b8d30f63 | 101:94b51fa4f797 |
|---|---|
| 1 use crate::conv::{BinaryQAndA, RadioQAndA}; | 1 use crate::conv::{BinaryQAndA, RadioQAndA}; |
| 2 use crate::conv::{Conversation, ErrorMsg, InfoMsg, MaskedQAndA, Message, QAndA}; | 2 use crate::conv::{Conversation, ErrorMsg, InfoMsg, MaskedQAndA, Message, QAndA}; |
| 3 use crate::libpam::answer::BinaryAnswer; | 3 use crate::libpam::answer::BinaryAnswer; |
| 4 use crate::libpam::answer::{Answer, Answers, TextAnswer}; | 4 use crate::libpam::answer::{Answer, Answers, TextAnswer}; |
| 5 use crate::libpam::memory::{CBinaryData, Immovable}; | 5 use crate::libpam::memory::CBinaryData; |
| 6 use crate::libpam::pam_ffi::AppData; | 6 use crate::libpam::pam_ffi::AppData; |
| 7 pub use crate::libpam::pam_ffi::LibPamConversation; | 7 pub use crate::libpam::pam_ffi::LibPamConversation; |
| 8 use crate::libpam::question::QuestionsTrait; | 8 use crate::libpam::question::QuestionsTrait; |
| 9 use crate::libpam::question::{Question, Questions}; | 9 use crate::libpam::question::{Question, Questions}; |
| 10 use crate::ErrorCode; | 10 use crate::ErrorCode; |
| 19 pub fn wrap<C: Conversation>(conv: &C) -> Self { | 19 pub fn wrap<C: Conversation>(conv: &C) -> Self { |
| 20 Self { | 20 Self { |
| 21 callback: Self::wrapper_callback::<C>, | 21 callback: Self::wrapper_callback::<C>, |
| 22 appdata: (conv as *const C).cast(), | 22 appdata: (conv as *const C).cast(), |
| 23 life: PhantomData, | 23 life: PhantomData, |
| 24 _marker: Immovable(PhantomData), | |
| 25 } | 24 } |
| 26 } | 25 } |
| 27 | 26 |
| 28 /// Passed as the conversation function into PAM for an owned handle. | 27 /// Passed as the conversation function into PAM for an owned handle. |
| 29 /// | 28 /// |
| 64 } | 63 } |
| 65 | 64 |
| 66 impl Conversation for LibPamConversation<'_> { | 65 impl Conversation for LibPamConversation<'_> { |
| 67 fn communicate(&self, messages: &[Message]) { | 66 fn communicate(&self, messages: &[Message]) { |
| 68 let internal = || { | 67 let internal = || { |
| 69 let questions = Questions::new(messages)?; | 68 let questions = Box::pin(Questions::new(messages)?); |
| 70 let mut response_pointer = std::ptr::null_mut(); | 69 let mut response_pointer = std::ptr::null_mut(); |
| 71 // SAFETY: We're calling into PAM with valid everything. | 70 // SAFETY: We're calling into PAM with valid everything. |
| 72 let result = unsafe { | 71 let result = unsafe { |
| 73 (self.callback)( | 72 (self.callback)( |
| 74 messages.len() as c_int, | 73 messages.len() as c_int, |
| 75 questions.ptr(), | 74 questions.as_ref().ptr(), |
| 76 &mut response_pointer, | 75 &mut response_pointer, |
| 77 self.appdata, | 76 self.appdata, |
| 78 ) | 77 ) |
| 79 }; | 78 }; |
| 80 ErrorCode::result_from(result)?; | 79 ErrorCode::result_from(result)?; |
