Skip to content

Commit 6ec968a

Browse files
committed
Merge #561: Fully describe safety requirements
e705bcf Fully describe safety requirements (Tobin C. Harding) Pull request description: 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 ## Note This is best effort only, will require some thought to review. To do this I read https://doc.rust-lang.org/reference/behavior-considered-undefined.html and then I flicked through `depend/secp256k1/src/secp256k1.c` and `util.h` to look for things that could cause things in the linked to list of UB. ACKs for top commit: apoelstra: ACK e705bcf Kixunil: ACK e705bcf Tree-SHA512: 0180d196f6d528e3c7a06da54ef58d015df19c351d98030453ae5c5e62e0565797b06169f27f5d8b40ea0b9adba377cadd45dd306c8213d0bdc98b20651766c7
2 parents 11001f4 + e705bcf commit 6ec968a

File tree

1 file changed

+18
-25
lines changed

1 file changed

+18
-25
lines changed

src/context.rs

+18-25
Original file line numberDiff line numberDiff line change
@@ -352,15 +352,22 @@ impl<'buf> Secp256k1<AllPreallocated<'buf>> {
352352

353353
/// Creates a context from a raw context.
354354
///
355+
/// The returned [`core::mem::ManuallyDrop`] context will never deallocate the memory pointed to
356+
/// by `raw_ctx` nor destroy the context. This may lead to memory leaks. `ManuallyDrop::drop`
357+
/// (or [`core::ptr::drop_in_place`]) will only destroy the context; the caller is required to
358+
/// free the memory.
359+
///
355360
/// # Safety
356-
/// This is highly unsafe, due to the number of conditions that aren't checked.
357-
/// * `raw_ctx` needs to be a valid Secp256k1 context pointer.
358-
/// that was generated by *exactly* the same code/version of the libsecp256k1 used here.
359-
/// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1
360-
/// when generating the context.
361-
/// * The user must handle the freeing of the context(using the correct functions) by himself.
362-
/// * Violating these may lead to Undefined Behavior.
363361
///
362+
/// This is highly unsafe due to a number of conditions that aren't checked, specifically:
363+
///
364+
/// * `raw_ctx` must be a valid pointer (live, aligned...) to memory that was initialized by
365+
/// `secp256k1_context_preallocated_create` (either called directly or from this library by
366+
/// one of the context creation methods - all of which call it internally).
367+
/// * The version of `libsecp256k1` used to create `raw_ctx` must be **exactly the one linked
368+
/// into this library**.
369+
/// * The lifetime of the `raw_ctx` pointer must outlive `'buf`.
370+
/// * `raw_ctx` must point to writable memory (cannot be `ffi::secp256k1_context_no_precomp`).
364371
pub unsafe fn from_raw_all(
365372
raw_ctx: NonNull<ffi::Context>,
366373
) -> ManuallyDrop<Secp256k1<AllPreallocated<'buf>>> {
@@ -380,18 +387,11 @@ impl<'buf> Secp256k1<SignOnlyPreallocated<'buf>> {
380387
#[inline]
381388
pub fn preallocate_signing_size() -> usize { Self::preallocate_size_gen() }
382389

383-
/// Creates a context from a raw context.
390+
/// Creates a context from a raw context that can only be used for signing.
384391
///
385392
/// # Safety
386393
///
387-
/// This is highly unsafe, due to the number of conditions that aren't checked.
388-
/// * `raw_ctx` needs to be a valid Secp256k1 context pointer.
389-
/// that was generated by *exactly* the same code/version of the libsecp256k1 used here.
390-
/// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1
391-
/// when generating the context.
392-
/// * The user must handle the freeing of the context(using the correct functions) by himself.
393-
/// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior.
394-
///
394+
/// Please see [`Secp256k1::from_raw_all`] for full documentation and safety requirements.
395395
pub unsafe fn from_raw_signing_only(
396396
raw_ctx: NonNull<ffi::Context>,
397397
) -> ManuallyDrop<Secp256k1<SignOnlyPreallocated<'buf>>> {
@@ -411,18 +411,11 @@ impl<'buf> Secp256k1<VerifyOnlyPreallocated<'buf>> {
411411
#[inline]
412412
pub fn preallocate_verification_size() -> usize { Self::preallocate_size_gen() }
413413

414-
/// Creates a context from a raw context.
414+
/// Creates a context from a raw context that can only be used for verification.
415415
///
416416
/// # Safety
417417
///
418-
/// This is highly unsafe, due to the number of conditions that aren't checked.
419-
/// * `raw_ctx` needs to be a valid Secp256k1 context pointer.
420-
/// that was generated by *exactly* the same code/version of the libsecp256k1 used here.
421-
/// * The capabilities (All/SignOnly/VerifyOnly) of the context *must* match the flags passed to libsecp256k1
422-
/// when generating the context.
423-
/// * The user must handle the freeing of the context(using the correct functions) by himself.
424-
/// * This list *is not* exhaustive, and any violation may lead to Undefined Behavior.
425-
///
418+
/// Please see [`Secp256k1::from_raw_all`] for full documentation and safety requirements.
426419
pub unsafe fn from_raw_verification_only(
427420
raw_ctx: NonNull<ffi::Context>,
428421
) -> ManuallyDrop<Secp256k1<VerifyOnlyPreallocated<'buf>>> {

0 commit comments

Comments
 (0)