-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Clone implementation for LocalRequest is unsound #1312
Comments
Absolutely fantastic find. I can confirm that this is, indeed, a soundness bug. The use of
This "proof" was written and argued on an earlier version of The fragility of this and other unsafe-soundness proofs in Rocket are that they are not machine checked. I had taken great care when writing the proof originally to check that it was correct, but future changes to the code are not subject to any machine-checked scrutiny, and recalling all cases in the original proof structure in response to a code change is a difficult proposition. As evidenced here, we clearly need to do better.
I am happy to have a
This is the approach I've taken in fixing this particular issue.
This is the approach I'd like to take. I am not sure if the safe |
The existing implementation of 'LocalRequest::clone()' mistakenly copied the internal 'Request' pointer from the existing 'LocalRequest' to the cloned 'LocalRequest'. This resulted in an aliased '*mut Request' pointer, a clear soundness issue. The fix in this commit is to clone the internal 'Request', replacing the internal pointer with the newly cloned 'Request' when producing the cloned 'LocalRequest'. A fix that removes all 'unsafe' code should be explored. Fixes #1312.
Informational advisory for rwf2/Rocket#1312
The Bug
LocalRequest is one of a few places that Rocket uses unsafe Rust. While auditing the code, I found that its Clone implementation is unsound.
First, let's look at the definition of LocalRequest, which implements a mutable Rc with a raw pointer:
https://github.com/SergioBenitez/Rocket/blob/ca4d1572d408fd8dd13db103926ad96da878126d/core/lib/src/local/request.rs#L68-L100
The comment justifies that it is safe to have LocalRequest and LocalResponse which share the same Request pointer because modification from LocalRequest is not observable from LocalResponse. However, LocalRequest's Clone implementation allows to create two LocalRequest that share the same Request raw pointer, which was not part of the justification:
https://github.com/SergioBenitez/Rocket/blob/ca4d1572d408fd8dd13db103926ad96da878126d/core/lib/src/local/request.rs#L477-L487
This ultimately permits the violation of aliasing rule with two LocalRequest instances that point to the same Request instance.
Proof of Concept
PoC code:
Output:
The PoC was tested on the following environment:
The PoC used a classic iterator invalidation to show it is possible to overwrite the pointer and the length of a string slice.
Is this a security bug?
Considering that
I believe the security impact of this bug is minimal. I think It is still worthwhile to file a RustSec advisory after the bug confirmation considering the people who want to be notified about unsound APIs.
Possible Fixes
I believe LocalRequest can be redesigned without breaking LocalRequest API with safe alternatives such as get_mut() or make_mut().
I think it is also possible to fix Clone to clone the internal Request, but the first solution which reduces the number of unsafe code should be preferred if possible.
The text was updated successfully, but these errors were encountered: