Merge rust-bitcoin/rust-secp256k1#548: fix soundness issue with `preallocated_gen_new`

1e6eb6cb4d shut clippy up (Andrew Poelstra)
f961497e69 context: introduce unsafe `PreallocatedContext` trait (Andrew Poelstra)

Pull request description:

  Stop this from being a generic function over all contexts, to only a function generic over contexts where we can bound the lifetime precisely. Introduces a new unsafe trait. I *believe* the only code this breaks was already unsound:
  * code that tried to use one of the `*Preallocated` context markers with an incorrect lifetime
  * code that tried to use `preallocated_gen_new` with a non-`*Preallocated` marker, which I believe we allowed before (I just noticed this now) and almost certainly would've led to UB on drop

  Fixes #543

ACKs for top commit:
  Kixunil:
    ACK 1e6eb6cb4d
  tcharding:
    ACK 1e6eb6cb4d

Tree-SHA512: 44eb4637a2f86d5b16d40174cb9e27f37cf8eb4f29546159dbbdcd3326d01f9de2f500ba732376dd84e67ebc3528c709d2d4e2aceb8a329bcb9fb9d25c9b89cb
This commit is contained in:
Andrew Poelstra 2022-12-04 17:38:41 +00:00
commit 29c13638dc
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 14 additions and 1 deletions

View File

@ -307,7 +307,20 @@ unsafe impl<'buf> Context for AllPreallocated<'buf> {
} }
} }
impl<'buf, C: Context + 'buf> Secp256k1<C> { /// Trait marking that a particular context object internally points to
/// memory that must outlive `'a`
///
/// # Safety
/// This trait is used internally to gate which context markers can safely
/// be used with the `preallocated_gen_new` function. Do not implement it
/// on your own structures.
pub unsafe trait PreallocatedContext<'a> {}
unsafe impl<'buf> PreallocatedContext<'buf> for AllPreallocated<'buf> {}
unsafe impl<'buf> PreallocatedContext<'buf> for SignOnlyPreallocated<'buf> {}
unsafe impl<'buf> PreallocatedContext<'buf> for VerifyOnlyPreallocated<'buf> {}
impl<'buf, C: Context + PreallocatedContext<'buf>> Secp256k1<C> {
/// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all). /// Lets you create a context with a preallocated buffer in a generic manner (sign/verify/all).
pub fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<C>, Error> { pub fn preallocated_gen_new(buf: &'buf mut [AlignedType]) -> Result<Secp256k1<C>, Error> {
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]