From fd206ab57cc9808d894aecdac74486f048ef5407 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Fri, 28 Aug 2020 15:20:19 +0300 Subject: [PATCH] Replace use of boxes with global allocator --- src/context.rs | 54 ++++++++++++++++++++++++++++---------------------- src/lib.rs | 12 +++++------ 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/context.rs b/src/context.rs index d78b3e1..1183de9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,7 +1,6 @@ use core::marker::PhantomData; -use core::mem::ManuallyDrop; -use ptr; -use ffi::{self, CPtr}; +use core::mem::{self, ManuallyDrop}; +use ffi::{self, CPtr, types::AlignedType}; use ffi::types::{c_uint, c_void}; use Error; use Secp256k1; @@ -50,7 +49,7 @@ pub unsafe trait Context : private::Sealed { /// A constant description of the context. const DESCRIPTION: &'static str; /// A function to deallocate the memory when the context is dropped. - unsafe fn deallocate(ptr: *mut [u8]); + unsafe fn deallocate(ptr: *mut u8, size: usize); } /// Marker trait for indicating that an instance of `Secp256k1` can be used for signing. @@ -93,6 +92,8 @@ mod std_only { impl private::Sealed for VerifyOnly {} use super::*; + use std::alloc; + const ALIGN_TO: usize = mem::align_of::(); /// Represents the set of capabilities needed for signing. pub enum SignOnly {} @@ -113,8 +114,9 @@ mod std_only { const FLAGS: c_uint = ffi::SECP256K1_START_SIGN; const DESCRIPTION: &'static str = "signing only"; - unsafe fn deallocate(ptr: *mut [u8]) { - let _ = Box::from_raw(ptr); + unsafe fn deallocate(ptr: *mut u8, size: usize) { + let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); + alloc::dealloc(ptr, layout); } } @@ -122,8 +124,9 @@ mod std_only { const FLAGS: c_uint = ffi::SECP256K1_START_VERIFY; const DESCRIPTION: &'static str = "verification only"; - unsafe fn deallocate(ptr: *mut [u8]) { - let _ = Box::from_raw(ptr); + unsafe fn deallocate(ptr: *mut u8, size: usize) { + let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); + alloc::dealloc(ptr, layout); } } @@ -131,8 +134,9 @@ mod std_only { const FLAGS: c_uint = VerifyOnly::FLAGS | SignOnly::FLAGS; const DESCRIPTION: &'static str = "all capabilities"; - unsafe fn deallocate(ptr: *mut [u8]) { - let _ = Box::from_raw(ptr); + unsafe fn deallocate(ptr: *mut u8, size: usize) { + let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); + alloc::dealloc(ptr, layout); } } @@ -142,12 +146,13 @@ mod std_only { #[cfg(target_arch = "wasm32")] ffi::types::sanity_checks_for_wasm(); - let buf = vec![0u8; Self::preallocate_size_gen()].into_boxed_slice(); - let ptr = Box::into_raw(buf); + let size = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) }; + let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); + let ptr = unsafe {alloc::alloc(layout)}; Secp256k1 { ctx: unsafe { ffi::secp256k1_context_preallocated_create(ptr as *mut c_void, C::FLAGS) }, phantom: PhantomData, - buf: ptr, + size, } } } @@ -181,12 +186,13 @@ mod std_only { impl Clone for Secp256k1 { fn clone(&self) -> Secp256k1 { - let clone_size = unsafe {ffi::secp256k1_context_preallocated_clone_size(self.ctx)}; - let ptr_buf = Box::into_raw(vec![0u8; clone_size].into_boxed_slice()); + let size = unsafe {ffi::secp256k1_context_preallocated_clone_size(self.ctx as _)}; + let layout = alloc::Layout::from_size_align(size, ALIGN_TO).unwrap(); + let ptr = unsafe {alloc::alloc(layout)}; Secp256k1 { - ctx: unsafe { ffi::secp256k1_context_preallocated_clone(self.ctx, ptr_buf as *mut c_void) }, + ctx: unsafe { ffi::secp256k1_context_preallocated_clone(self.ctx, ptr as *mut c_void) }, phantom: PhantomData, - buf: ptr_buf, + size, } } } @@ -202,7 +208,7 @@ unsafe impl<'buf> Context for SignOnlyPreallocated<'buf> { const FLAGS: c_uint = ffi::SECP256K1_START_SIGN; const DESCRIPTION: &'static str = "signing only"; - unsafe fn deallocate(_ptr: *mut [u8]) { + unsafe fn deallocate(_ptr: *mut u8, _size: usize) { // Allocated by the user } } @@ -211,7 +217,7 @@ unsafe impl<'buf> Context for VerifyOnlyPreallocated<'buf> { const FLAGS: c_uint = ffi::SECP256K1_START_VERIFY; const DESCRIPTION: &'static str = "verification only"; - unsafe fn deallocate(_ptr: *mut [u8]) { + unsafe fn deallocate(_ptr: *mut u8, _size: usize) { // Allocated by the user } } @@ -220,7 +226,7 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> { const FLAGS: c_uint = SignOnlyPreallocated::FLAGS | VerifyOnlyPreallocated::FLAGS; const DESCRIPTION: &'static str = "all capabilities"; - unsafe fn deallocate(_ptr: *mut [u8]) { + unsafe fn deallocate(_ptr: *mut u8, _size: usize) { // Allocated by the user } } @@ -241,7 +247,7 @@ impl<'buf, C: Context + 'buf> Secp256k1 { C::FLAGS) }, phantom: PhantomData, - buf: buf as *mut [u8], + size: 0, // We don't care about the size because it's the caller responsibility to deallocate. }) } } @@ -271,7 +277,7 @@ impl<'buf> Secp256k1> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, - buf: ptr::null_mut::<[u8;0]>() as *mut [u8] , + size: 0, // We don't care about the size because it's the caller responsibility to deallocate. }) } } @@ -303,7 +309,7 @@ impl<'buf> Secp256k1> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, - buf: ptr::null_mut::<[u8;0]>() as *mut [u8] , + size: 0, // We don't care about the size because it's the caller responsibility to deallocate. }) } } @@ -335,7 +341,7 @@ impl<'buf> Secp256k1> { ManuallyDrop::new(Secp256k1 { ctx: raw_ctx, phantom: PhantomData, - buf: ptr::null_mut::<[u8;0]>() as *mut [u8] , + size: 0, // We don't care about the size because it's the caller responsibility to deallocate. }) } } diff --git a/src/lib.rs b/src/lib.rs index 483ddd9..cf39ac1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -558,7 +558,7 @@ impl std::error::Error for Error {} pub struct Secp256k1 { ctx: *mut ffi::Context, phantom: PhantomData, - buf: *mut [u8], + size: usize, } // The underlying secp context does not contain any references to memory it does not own @@ -607,7 +607,7 @@ impl Drop for Secp256k1 { fn drop(&mut self) { unsafe { ffi::secp256k1_context_preallocated_destroy(self.ctx); - C::deallocate(self.buf); + C::deallocate(self.ctx as _, self.size); } } } @@ -781,10 +781,10 @@ mod tests { let ctx_sign = unsafe { ffi::secp256k1_context_create(SignOnlyPreallocated::FLAGS) }; let ctx_vrfy = unsafe { ffi::secp256k1_context_create(VerifyOnlyPreallocated::FLAGS) }; - let buf: *mut [u8] = &mut [0u8;0] as _; - let full: Secp256k1 = Secp256k1{ctx: ctx_full, phantom: PhantomData, buf}; - let sign: Secp256k1 = Secp256k1{ctx: ctx_sign, phantom: PhantomData, buf}; - let vrfy: Secp256k1 = Secp256k1{ctx: ctx_vrfy, phantom: PhantomData, buf}; + let size = 0; + let full: Secp256k1 = Secp256k1{ctx: ctx_full, phantom: PhantomData, size}; + let sign: Secp256k1 = Secp256k1{ctx: ctx_sign, phantom: PhantomData, size}; + let vrfy: Secp256k1 = Secp256k1{ctx: ctx_vrfy, phantom: PhantomData, size}; let (sk, pk) = full.generate_keypair(&mut thread_rng()); let msg = Message::from_slice(&[2u8; 32]).unwrap();