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

rust: Add Send bound to SecureSessionTransport trait #898

Merged
merged 3 commits into from
Jan 19, 2022

Conversation

ilammy
Copy link
Collaborator

@ilammy ilammy commented Jan 19, 2022

New Clippy 1.58 has found an unsoundness in RustThemis: unsafe impl for SecureSession make it Send – safe to pass over to a different thread – but in fact it's not safe to do that unless SecureSessionTransport implementation used by SecureSession is also Send, which was expected but never required. Well, now it is required.

This would break application code that uses SecureSessionTransport implementations that are !Send (e.g., using Rc inside, or raw pointers). This is not safe if SecureSession is moved to another thread, but it should be okay if it stays on the same thread as its transport.

I believe that most applications will not be affected by this change. If someone is really out there using !Send transports, they'd come complaining, then I'd decide what to do: either tell them “you're doing it wrong”, or make a patch release that make it possible to SecureSession to be !Send as well.

For now, my goal is to fix a warning from Clippy on CI.

Checklist

  • Change is covered by automated tests
  • The coding guidelines are followed
  • Changelog is updated

Parent struct SecureSession expects to implement Send at all times.
However, it would be unsound if SecureSessionTransport does not
implement Send. This is a blunder in the original implementation.

Well, let's hope that all reasonable implementations are already Send,
and just require SecureSessionTransport to be Send. I'd rather make
0.15.1 later with some ugly generic fix if some users show up with
a genuine use-case for !Send transport callbacks.

That said, SecureSession could be made to implement Send based on the
type of SecureSessionTransport it uses. However, I don't want to get
generics into the mix unless I have to, since that might turn out
to be another breaking change.
Because the first "unsafe impl" went so well, let's add another one.
This makes sure that the first "unsafe impl" is well-founded: that is,
all fields are actually Send -- compiler does not check that, trusting
our "unsafe" but recent Clippy does, and it complained about it.

With "Box<dyn SecureSessionTransport>" being Send now, the only
remaining thing that is !Send is secure_session_user_callbacks_t,
because of that "void* user_context" pointer in it. The pointer
points to SecureSessionContext struct itself, which make it not only
unsafe to send across threads, it's unsafe to move it at all. That's
why we put it in a Box which stays in the same place on heap until
SecureSession is dropped.

I believe this should be safe now.
@ilammy ilammy added compatibility Backward and forward compatibility, platform interoperability issues, breaking changes W-RustThemis 🦀 Wrapper: Rust-Themis, Rust API, Cargo crates labels Jan 19, 2022
@ilammy
Copy link
Collaborator Author

ilammy commented Jan 19, 2022

Ha-ha, "all users", said I. Our own integration tests are those affected users, it seems.

@vixentael
Copy link
Contributor

Should we update Thread Safety guidelines too?
https://docs.cossacklabs.com/themis/debugging/thread-safety/#secure-comparator-secure-session

Make sure that newly added Send bound it satisfied. The closures we use
are safe to Send across thread boundaries, but the utilities did not
preserve this bound as they themselves use type erasure.
@ilammy
Copy link
Collaborator Author

ilammy commented Jan 19, 2022

Should we update Thread Safety guidelines too?

I think it will be okay as is, no need to add any extra warnings there.

Contrary to C++, if a Rust application tries to use SecureSession in unsafe way, the compiler will show an error. Send and Sync traits are there to help. In other languages we have to resort to "pls don't do that, it's not safe" in documentation because it's not possible to enforce the requirements at compile-time.

@vixentael
Copy link
Contributor

In other languages .. it's not possible to enforce the requirements at compile-tim

Rust rules!

@ilammy ilammy merged commit 3e9e51e into cossacklabs:master Jan 19, 2022
@ilammy ilammy deleted the unsafe-send branch January 19, 2022 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Backward and forward compatibility, platform interoperability issues, breaking changes W-RustThemis 🦀 Wrapper: Rust-Themis, Rust API, Cargo crates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants