Skip to content
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

Internal "unsoundness" in sign_ecdsa_with_noncedata_pointer #481

Closed
Kixunil opened this issue Aug 2, 2022 · 6 comments · Fixed by #483
Closed

Internal "unsoundness" in sign_ecdsa_with_noncedata_pointer #481

Kixunil opened this issue Aug 2, 2022 · 6 comments · Fixed by #483

Comments

@Kixunil
Copy link
Collaborator

Kixunil commented Aug 2, 2022

While sign_ecdsa_with_noncedata_pointer is private so consumers can't cause UB in safe code it's still considered wrong to not mark the function unsafe because it's confusing. From my understanding such issue caused horrible flamewar at actix-web crate.

Given that the function is called either with &[u8; 32] or null pointer I propose to change it to accept Option<&[u8; 32]> instead. Internally, it does the same thing thanks to layout optimizations but is safer. We supply null pointer if there is None and the pointer obtained from reference if there is Some.

@apoelstra
Copy link
Member

I think it'd be simpler to just mark it unsafe. If we accept a Option<&[u8; 32]> then we have to convert that to a pointer inside the function before calling FFI (I understand the Option optimization but don't believe we can depend on that when crossing a FFI boundary).

Alternately: making the function unsafe and removing the internal unsafe {} saves two lines of code. Adding a conversion requires an extra line of code :).

@Kixunil
Copy link
Collaborator Author

Kixunil commented Aug 2, 2022

don't believe we can depend on that when crossing a FFI boundary

Actually, we can! rustc would complain if we couldn't but it doesn't complain. Yes this is a documented feature, guaranteed to be correct.

Edit: I believe even if this wasn't true converting option would've been better.

@apoelstra
Copy link
Member

Ok, nice. Concept ACK doing this. I can PR if you'd like, though if you're up for it that might be faster :)

@Kixunil
Copy link
Collaborator Author

Kixunil commented Aug 3, 2022

Got a bunch of things to do, so I probably can't sooner than in 24 hours.

@apoelstra
Copy link
Member

So, we can't actually change the FFI signature to take a Option<&[u8; 32]> because the signature on the C side is a void* not a whatever_u8_32_would_be_in_c* -- and in fact, this is not, in general, a pointer to 32 bytes of data. (It just happens to be with the rfc6979 nonce function that we're calling here.)

I can certainly clean up the unsafety but I don't see a way to use the nullable pointer trick.

apoelstra added a commit to apoelstra/rust-secp256k1 that referenced this issue Aug 11, 2022
An internal function had a non-unsafe signature but could be called
with data that would cause it to exhibit UB. Move the unsafety inside
of the function so that the function signature now enforces soundness.

Fixes rust-bitcoin#481
@Kixunil
Copy link
Collaborator Author

Kixunil commented Aug 11, 2022

Ah, good point. match is still better and it'll almost certainly get optimized out anyway.

apoelstra added a commit that referenced this issue Aug 13, 2022
0f29348 move some unsafe code inside an unsafe{} boundary (Andrew Poelstra)

Pull request description:

  An internal function had a non-unsafe signature but could be called
  with data that would cause it to exhibit UB. Move the unsafety inside
  of the function so that the function signature now enforces soundness.

  Fixes #481

Top commit has no ACKs.

Tree-SHA512: b1ffc643aa11e9c8d0b7a32965a1504da14f6ac3f9e0aa175d2c09d7d7b6bf84e228f64e1f57800d75500e2c65066a4991f0070a3a1d0a19c1bd84ca0dd44363
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 a pull request may close this issue.

2 participants