-
Notifications
You must be signed in to change notification settings - Fork 704
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
Fix unsoundness via impure AsRef #705
base: master
Are you sure you want to change the base?
Conversation
Could you please elaborate in what case exactly situation UB can occur? |
Doesn't the borrow checker check such "undefined behaviour" in a compile time? |
With let key = evil.as_ref().as_ptr(); // Pointer to "hi"
let key_len = evil.as_ref().len(); // Length of "there" Then, passing The fix is simply to only ever call The implementation of |
I think technically it wouldn't be a safe code, because out-of-bounds reads can only occur through FFI border and FFI functions are unsafe. I see your point now and I think that using |
The FFI functions are unsafe, because the compiler cannot check the required invariants, but this library tries to offer a safe interface. So it needs to maintain all required invariants. Suppose a buggy string interning library (written entirely without https://docs.rs/dtolnay/latest/dtolnay/macro._03__soundness_bugs.html#soundness puts it well:
|
* fix issues with set_sample_ratio Signed-off-by: tabokie <xy.tao@outlook.com> * delete instead Signed-off-by: tabokie <xy.tao@outlook.com>
The case you've provided could be possible only in multithreaded code. In such a case, you should guarantee sync access to the database on your side. |
For example, yes. And one of Rusts main selling points is to encode such requirements in the type system, so that they can be checked at compile time. In most other languages such a requirement would be implied and that would be that. In Rust, libraries generally aim to be sound, i.e., to only rely on safety invariants that the compiler can enforce or mark the function as unsafe and document the exact requirements. This requires some special care to uphold invariants when writing unsafe code, to not rely on any invariants that are only implied, not enforced, as can be seen here. Fortunately the fix is simple. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have convinced me. 🙃
I want a real example of the code with rocksdb that reproduces the issue this PR "fixes". |
Sure. I have completed the example from the PR description and added it as a test case.
Since this is UB, the crash is not guaranteed, but I consistently see it if one of the return values of the |
An impure
AsRef
implementation can cause UB in safe code, by presenting different slices on each call.