Skip to content

secp256k1-sys: remove CPtr impl for &[T] and associated weirdness #816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

apoelstra
Copy link
Member

Fixes the signature of secp256k1_ec_pubkey_sort to use *mut rather than *const.

Separately, our call to secp256k1_ec_pubkey_sort, while correctly starting from a &mut [PublicKey], briefly constructed a &[ffi::PublicKey] slice before obtaining a *mut pointer from this. This was unsound for completely unnecessary reasons, and only compiled because we have an impl of the CPtr trait for &[T], which provides a as_mut_c_ptr() method which basically cannot be safely used.

Removing that &[T] impl revealed another case where it was (unnecessarily) being used: in EllSwift::shared_secret, where we use it to obtain a *mut pointer from a &[u8], which we pass across the FFI boundary which simply drops it.

In rust-bitcoin#794 I accidentally changed a *mut to *const. This is incorrect and
unsound.
We take an optional `data` argument to `shared_secret`, but the upstream
function we call never uses it. However, this argument *does* use the
CPtr impl on &[T] in order to obtain a pointer to pass across the FFI
boundary. This impl is very dangerous, and its use here is sound only
because the resulting pointer is never used.

See
rust-bitcoin#627 (comment)
In sort_pubkeys() we convert a slice of PublicKeys to a slice of
ffi::PublicKeys. This is OK, because we have repr(transparent) allowing
us to do this. But we do so in an unnecessarily-complicated way, which
winds up going through the CPtr implementation on &[u8], and which I
think may technically be unsound.

Simplify it and avoid using this impl. The next commit will remove it
entirely.
@apoelstra
Copy link
Member Author

I am equivocating on whether I should backport the last commit to secp256k1-sys 0.9.x, 0.10.x and 0.11.x. Doing so would be a breaking change (and would break rust-secp256k1, necessitating a minor release of those) and technically speaking there is no unsoundness here so it is not urgent to do so.

But on the other hand, <&[T]>::as_c_mut_ptr is really dangerous, never needed to be exposed except that we made a mistake, and we managed to cut ourselves with it and nearly released an unsound version of the library with it. Which we caught entirely by accident -- I incorrectly changed a ffi signature near the UB, which Kix noticed and complained about, and in my investigation I found it.

@apoelstra
Copy link
Member Author

For anyone struggling to follow my story here -- checkout master remove the impl CPtr for &[T] block in secp256k1-sys/src/lib.rs, and see what breaks.

Copy link
Member Author

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On debae90 successfully ran local tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant