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 |
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)?; |