From 460e6ba75ae0dad8574cbeace6c6b33569ce89df Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Fri, 20 Aug 2021 14:47:09 +0200 Subject: [PATCH] Have the engine pass a malloc and free to Sequoia's pgp_init_. --- src/ffi.rs | 11 +++++++++++ src/lib.rs | 12 ++++++++++-- src/pep/session.rs | 24 ++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index b67e267..9a3ba28 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -1,3 +1,14 @@ +use libc::{ + c_void, + size_t, +}; + +/// How to free the memory allocated by the callback. +pub type Free = unsafe extern "C" fn(*mut c_void); + +/// How to free the memory allocated by the callback. +pub type Malloc = unsafe extern "C" fn(size_t) -> *mut c_void; + // Wraps an ffi function. // // This wrapper allows the function to return a Result. The Ok diff --git a/src/lib.rs b/src/lib.rs index cb857ab..fa5868e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,6 @@ use std::time::{ use libc::{ c_char, c_uint, - malloc, size_t, time_t, }; @@ -106,6 +105,8 @@ use pep::{ Timestamp, }; #[macro_use] mod ffi; +use ffi::{Malloc, Free}; + mod keystore; use keystore::Keystore; mod buffer; @@ -199,9 +200,12 @@ fn _pgp_get_decrypted_key_iter<'a, I>(iter: I, pass: Option<&Password>) } } + // PEP_STATUS pgp_init(PEP_SESSION session, bool in_first) ffi!(fn pgp_init_(session: *mut Session, _in_first: bool, per_user_directory: *const c_char, + malloc: Malloc, + free: Free, session_size: c_uint, session_cookie_offset: c_uint, session_curr_passphrase_offset: c_uint, @@ -273,7 +277,7 @@ ffi!(fn pgp_init_(session: *mut Session, _in_first: bool, }; let ks = keystore::Keystore::init(Path::new(per_user_directory))?; - session.init(ks); + session.init(ks, malloc, free); Ok(()) }); @@ -701,6 +705,7 @@ ffi!(fn pgp_decrypt_and_verify(session: *mut Session, -> Result<()> { let session = Session::as_mut(session); + let malloc = session.malloc(); if ctext.is_null() { return Err(Error::IllegalValue( @@ -943,6 +948,7 @@ ffi!(fn pgp_sign_only( -> Result<()> { let session = Session::as_mut(session); + let malloc = session.malloc(); if fpr.is_null() { return Err(Error::IllegalValue( @@ -1048,6 +1054,7 @@ fn pgp_encrypt_sign_optional( tracer!(*crate::TRACE, "pgp_encrypt_sign_optional"); let session = Session::as_mut(session); + let malloc = session.malloc(); if ptext.is_null() { return Err(Error::IllegalValue( @@ -1679,6 +1686,7 @@ ffi!(fn pgp_export_keydata(session: *mut Session, -> Result<()> { let session = Session::as_mut(session); + let malloc = session.malloc(); if fpr.is_null() { return Err(Error::IllegalValue("fpr must not be NULL".into())); diff --git a/src/pep/session.rs b/src/pep/session.rs index 971e4ac..37a8a00 100644 --- a/src/pep/session.rs +++ b/src/pep/session.rs @@ -11,11 +11,14 @@ use crate::Error; use crate::Keystore; use crate::PepCipherSuite; use crate::Result; +use crate::{Malloc, Free}; const MAGIC: u64 = 0xE3F3_05AD_48EE_0DF5; pub struct State { ks: Keystore, + malloc: Malloc, + free: Free, magic: u64, } @@ -72,6 +75,8 @@ impl Session { version: ptr::null(), state: Box::into_raw(Box::new(State { ks: Keystore::init_in_memory().unwrap(), + malloc: libc::malloc, + free: libc::free, magic: MAGIC, })), curr_passphrase: ptr::null(), @@ -82,12 +87,16 @@ impl Session { } pub fn init(&mut self, - ks: Keystore) + ks: Keystore, + malloc: Malloc, + free: Free) { assert!(self.state.is_null()); self.state = Box::into_raw(Box::new(State { ks: ks, + malloc: malloc, + free: free, magic: MAGIC, })); } @@ -112,6 +121,16 @@ impl Session { &mut State::as_mut(self.state).ks } + /// Returns the application's malloc routine. + pub fn malloc(&self) -> Malloc { + State::as_mut(self.state).malloc + } + + /// Returns the application's free routine. + pub fn free(&self) -> Free { + State::as_mut(self.state).free + } + /// Returns the value of curr_passphrase. pub fn curr_passphrase(&self) -> Option { unsafe { @@ -190,7 +209,8 @@ mod tests { session.deinit(); // If the state pointer is non-NULL, this will panic. - session.init(Keystore::init_in_memory().unwrap()); + session.init(Keystore::init_in_memory().unwrap(), + libc::malloc, libc::free); let ks = session.keystore() as *mut _; let ks2 = session.keystore() as *mut _; assert!(ptr::eq(ks, ks2)); -- GitLab