From e705bcffb5d854866934186b60c5431a6c0084c2 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 8 Dec 2022 12:34:33 +1100 Subject: [PATCH] Fully describe safety requirements Currently we have a wildcard on safety requirements, saying more or less "plus a bunch of other stuff we don't mention". This is not helpful. Attempt to fully describe the safety requirements of creating a context from a raw context (all, signing only, and verification only). Fix: #544 --- src/context.rs | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/context.rs b/src/context.rs index 10a2210..c59017b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -352,15 +352,22 @@ impl<'buf> Secp256k1> { /// Creates a context from a raw context. /// - /// # Safety - /// This is highly unsafe, due to the number of conditions that aren't checked. - /// * `raw_ctx` needs to be a valid Secp256k1 context pointer. - /// that was generated by *exactly* the same code/version of the libsecp256k1 used here. - /// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1 - /// when generating the context. - /// * The user must handle the freeing of the context(using the correct functions) by himself. - /// * Violating these may lead to Undefined Behavior. + /// The returned [`core::mem::ManuallyDrop`] context will never deallocate the memory pointed to + /// by `raw_ctx` nor destroy the context. This may lead to memory leaks. `ManuallyDrop::drop` + /// (or [`core::ptr::drop_in_place`]) will only destroy the context; the caller is required to + /// free the memory. /// + /// # Safety + /// + /// This is highly unsafe due to a number of conditions that aren't checked, specifically: + /// + /// * `raw_ctx` must be a valid pointer (live, aligned...) to memory that was initialized by + /// `secp256k1_context_preallocated_create` (either called directly or from this library by + /// one of the context creation methods - all of which call it internally). + /// * The version of `libsecp256k1` used to create `raw_ctx` must be **exactly the one linked + /// into this library**. + /// * The lifetime of the `raw_ctx` pointer must outlive `'buf`. + /// * `raw_ctx` must point to writable memory (cannot be `ffi::secp256k1_context_no_precomp`). pub unsafe fn from_raw_all( raw_ctx: NonNull, ) -> ManuallyDrop>> { @@ -380,18 +387,11 @@ impl<'buf> Secp256k1> { #[inline] pub fn preallocate_signing_size() -> usize { Self::preallocate_size_gen() } - /// Creates a context from a raw context. + /// Creates a context from a raw context that can only be used for signing. /// /// # Safety /// - /// This is highly unsafe, due to the number of conditions that aren't checked. - /// * `raw_ctx` needs to be a valid Secp256k1 context pointer. - /// that was generated by *exactly* the same code/version of the libsecp256k1 used here. - /// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1 - /// when generating the context. - /// * The user must handle the freeing of the context(using the correct functions) by himself. - /// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior. - /// + /// Please see [`Secp256k1::from_raw_all`] for full documentation and safety requirements. pub unsafe fn from_raw_signing_only( raw_ctx: NonNull, ) -> ManuallyDrop>> { @@ -411,18 +411,11 @@ impl<'buf> Secp256k1> { #[inline] pub fn preallocate_verification_size() -> usize { Self::preallocate_size_gen() } - /// Creates a context from a raw context. + /// Creates a context from a raw context that can only be used for verification. /// /// # Safety /// - /// This is highly unsafe, due to the number of conditions that aren't checked. - /// * `raw_ctx` needs to be a valid Secp256k1 context pointer. - /// that was generated by *exactly* the same code/version of the libsecp256k1 used here. - /// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1 - /// when generating the context. - /// * The user must handle the freeing of the context(using the correct functions) by himself. - /// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior. - /// + /// Please see [`Secp256k1::from_raw_all`] for full documentation and safety requirements. pub unsafe fn from_raw_verification_only( raw_ctx: NonNull, ) -> ManuallyDrop>> {