Skip to content

Commit 1e711f1

Browse files
authored
Merge pull request #184 from elichai/2019-11-context
Fix a safety problem and make the Context trait unimplementable
2 parents 47b2555 + 9522f7e commit 1e711f1

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

src/context.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ use Secp256k1;
88
pub use self::std_only::*;
99

1010
/// A trait for all kinds of Context's that Lets you define the exact flags and a function to deallocate memory.
11-
/// * DO NOT * implement it for your own types.
12-
pub unsafe trait Context {
11+
/// It shouldn't be possible to implement this for types outside this crate.
12+
pub unsafe trait Context : private::Sealed {
1313
/// Flags for the ffi.
1414
const FLAGS: c_uint;
1515
/// A constant description of the context.
1616
const DESCRIPTION: &'static str;
1717
/// A function to deallocate the memory when the context is dropped.
18-
fn deallocate(ptr: *mut [u8]);
18+
unsafe fn deallocate(ptr: *mut [u8]);
1919
}
2020

2121
/// Marker trait for indicating that an instance of `Secp256k1` can be used for signing.
@@ -39,8 +39,24 @@ pub struct AllPreallocated<'buf> {
3939
phantom: PhantomData<&'buf ()>,
4040
}
4141

42+
mod private {
43+
use super::*;
44+
// A trick to prevent users from implementing a trait.
45+
// on one hand this trait is public, on the other it's in a private module
46+
// so it's not visible to anyone besides it's parent (the context module)
47+
pub trait Sealed {}
48+
49+
impl<'buf> Sealed for AllPreallocated<'buf> {}
50+
impl<'buf> Sealed for VerifyOnlyPreallocated<'buf> {}
51+
impl<'buf> Sealed for SignOnlyPreallocated<'buf> {}
52+
}
53+
4254
#[cfg(feature = "std")]
4355
mod std_only {
56+
impl private::Sealed for SignOnly {}
57+
impl private::Sealed for All {}
58+
impl private::Sealed for VerifyOnly {}
59+
4460
use super::*;
4561

4662
/// Represents the set of capabilities needed for signing.
@@ -62,26 +78,26 @@ mod std_only {
6278
const FLAGS: c_uint = ffi::SECP256K1_START_SIGN;
6379
const DESCRIPTION: &'static str = "signing only";
6480

65-
fn deallocate(ptr: *mut [u8]) {
66-
let _ = unsafe { Box::from_raw(ptr) };
81+
unsafe fn deallocate(ptr: *mut [u8]) {
82+
let _ = Box::from_raw(ptr);
6783
}
6884
}
6985

7086
unsafe impl Context for VerifyOnly {
7187
const FLAGS: c_uint = ffi::SECP256K1_START_VERIFY;
7288
const DESCRIPTION: &'static str = "verification only";
7389

74-
fn deallocate(ptr: *mut [u8]) {
75-
let _ = unsafe { Box::from_raw(ptr) };
90+
unsafe fn deallocate(ptr: *mut [u8]) {
91+
let _ = Box::from_raw(ptr);
7692
}
7793
}
7894

7995
unsafe impl Context for All {
8096
const FLAGS: c_uint = VerifyOnly::FLAGS | SignOnly::FLAGS;
8197
const DESCRIPTION: &'static str = "all capabilities";
8298

83-
fn deallocate(ptr: *mut [u8]) {
84-
let _ = unsafe { Box::from_raw(ptr) };
99+
unsafe fn deallocate(ptr: *mut [u8]) {
100+
let _ = Box::from_raw(ptr);
85101
}
86102
}
87103

@@ -136,7 +152,6 @@ mod std_only {
136152
}
137153
}
138154
}
139-
140155
}
141156

142157
impl<'buf> Signing for SignOnlyPreallocated<'buf> {}
@@ -149,7 +164,7 @@ unsafe impl<'buf> Context for SignOnlyPreallocated<'buf> {
149164
const FLAGS: c_uint = ffi::SECP256K1_START_SIGN;
150165
const DESCRIPTION: &'static str = "signing only";
151166

152-
fn deallocate(_ptr: *mut [u8]) {
167+
unsafe fn deallocate(_ptr: *mut [u8]) {
153168
// Allocated by the user
154169
}
155170
}
@@ -158,7 +173,7 @@ unsafe impl<'buf> Context for VerifyOnlyPreallocated<'buf> {
158173
const FLAGS: c_uint = ffi::SECP256K1_START_VERIFY;
159174
const DESCRIPTION: &'static str = "verification only";
160175

161-
fn deallocate(_ptr: *mut [u8]) {
176+
unsafe fn deallocate(_ptr: *mut [u8]) {
162177
// Allocated by the user
163178
}
164179
}
@@ -167,7 +182,7 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> {
167182
const FLAGS: c_uint = SignOnlyPreallocated::FLAGS | VerifyOnlyPreallocated::FLAGS;
168183
const DESCRIPTION: &'static str = "all capabilities";
169184

170-
fn deallocate(_ptr: *mut [u8]) {
185+
unsafe fn deallocate(_ptr: *mut [u8]) {
171186
// Allocated by the user
172187
}
173188
}

src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,10 @@ impl<C: Context> Eq for Secp256k1<C> { }
574574

575575
impl<C: Context> Drop for Secp256k1<C> {
576576
fn drop(&mut self) {
577-
unsafe { ffi::secp256k1_context_preallocated_destroy(self.ctx) };
578-
C::deallocate(self.buf);
577+
unsafe {
578+
ffi::secp256k1_context_preallocated_destroy(self.ctx);
579+
C::deallocate(self.buf);
580+
}
579581
}
580582
}
581583

0 commit comments

Comments
 (0)