Mercurial > crates > nonstick
comparison src/libpam/handle.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 | 94eb11cb1798 |
comparison
equal
deleted
inserted
replaced
| 100:3f11b8d30f63 | 101:94b51fa4f797 |
|---|---|
| 9 use crate::logging::Level; | 9 use crate::logging::Level; |
| 10 use crate::{Conversation, EnvironMap, Flags, PamHandleApplication, PamHandleModule}; | 10 use crate::{Conversation, EnvironMap, Flags, PamHandleApplication, PamHandleModule}; |
| 11 use num_enum::{IntoPrimitive, TryFromPrimitive}; | 11 use num_enum::{IntoPrimitive, TryFromPrimitive}; |
| 12 use std::cell::Cell; | 12 use std::cell::Cell; |
| 13 use std::ffi::{c_char, c_int, CString}; | 13 use std::ffi::{c_char, c_int, CString}; |
| 14 use std::marker::PhantomData; | |
| 15 use std::ops::{Deref, DerefMut}; | 14 use std::ops::{Deref, DerefMut}; |
| 16 use std::ptr; | 15 use std::ptr; |
| 17 | 16 |
| 18 /// Owner for a PAM handle. | 17 /// Owner for a PAM handle. |
| 19 struct HandleWrap(*mut LibPamHandle); | 18 struct HandleWrap(*mut LibPamHandle); |
| 31 } | 30 } |
| 32 } | 31 } |
| 33 | 32 |
| 34 /// An owned PAM handle. | 33 /// An owned PAM handle. |
| 35 pub struct OwnedLibPamHandle<'a> { | 34 pub struct OwnedLibPamHandle<'a> { |
| 35 /// The handle itself. | |
| 36 handle: HandleWrap, | 36 handle: HandleWrap, |
| 37 /// The last return value from the handle. | |
| 37 last_return: Cell<Result<()>>, | 38 last_return: Cell<Result<()>>, |
| 38 _conversation_lifetime: PhantomData<&'a mut ()>, | 39 /// If set, the Conversation that this PAM handle owns. |
| 40 conversation: Option<Box<LibPamConversation<'a>>>, | |
| 39 } | 41 } |
| 40 | 42 |
| 41 #[derive(Debug, PartialEq)] | 43 #[derive(Debug, PartialEq)] |
| 42 pub struct HandleBuilder { | 44 pub struct HandleBuilder { |
| 43 service_name: String, | 45 service_name: String, |
| 75 fn start( | 77 fn start( |
| 76 service_name: String, | 78 service_name: String, |
| 77 username: Option<String>, | 79 username: Option<String>, |
| 78 conversation: &impl Conversation, | 80 conversation: &impl Conversation, |
| 79 ) -> Result<Self> { | 81 ) -> Result<Self> { |
| 80 let conv = LibPamConversation::wrap(conversation); | 82 let conv = Box::new(LibPamConversation::wrap(conversation)); |
| 81 let service_cstr = CString::new(service_name).map_err(|_| ErrorCode::ConversationError)?; | 83 let service_cstr = CString::new(service_name).map_err(|_| ErrorCode::ConversationError)?; |
| 82 let username_cstr = memory::prompt_ptr(memory::option_cstr(username.as_deref())?.as_ref()); | 84 let username_cstr = memory::prompt_ptr(memory::option_cstr(username.as_deref())?.as_ref()); |
| 83 | 85 |
| 84 let mut handle: *mut LibPamHandle = ptr::null_mut(); | 86 let mut handle: *mut LibPamHandle = ptr::null_mut(); |
| 85 // SAFETY: We've set everything up properly to call `pam_start`. | 87 // SAFETY: We've set everything up properly to call `pam_start`. |
| 86 // The returned value will be a valid pointer provided the result is OK. | 88 // The returned value will be a valid pointer provided the result is OK. |
| 87 let result = | 89 let result = unsafe { |
| 88 unsafe { pam_ffi::pam_start(service_cstr.as_ptr(), username_cstr, &conv, &mut handle) }; | 90 pam_ffi::pam_start( |
| 91 service_cstr.as_ptr(), | |
| 92 username_cstr, | |
| 93 conv.as_ref(), | |
| 94 &mut handle, | |
| 95 ) | |
| 96 }; | |
| 89 ErrorCode::result_from(result)?; | 97 ErrorCode::result_from(result)?; |
| 90 Ok(Self { | 98 Ok(Self { |
| 91 handle: HandleWrap(handle), | 99 handle: HandleWrap(handle), |
| 92 last_return: Cell::new(Ok(())), | 100 last_return: Cell::new(Ok(())), |
| 93 _conversation_lifetime: Default::default(), | 101 conversation: Some(conv), |
| 94 }) | 102 }) |
| 95 } | 103 } |
| 96 } | 104 } |
| 97 | 105 |
| 98 impl PamHandleApplication for OwnedLibPamHandle<'_> { | 106 impl PamHandleApplication for OwnedLibPamHandle<'_> { |
