-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Miri violation in std/src/sys/sgx/waitqueue/unsafe_list.rs #114581
Comments
@raoulstrackx i see you have a PR touching the waitqueue |
Hi @Nilstrieb I'm not familiar with Stacked Borrows but I took another look at the
|
Also, I'm not sure why the code uses |
I think the comment of @raoulstrackx makes sense. In this case I suppose miri is a bit pedantic (not sure though I am quite new to Stacked Borrows myself). I have experimented with pieces of simplified code. |
About stacked borrows, check out https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md I don't think Miri is wrong here. Miri faithfully implements stacked borrows. Stacked borrows are known to be more strict than ideal, and the new tree borrows is less strict (probably too lax) so it's also worth trying out that using the Miri flag, but in general for now it's a good idea to have all code in std conform with stacked borrows. |
It's not just Miri, we also tell LLVM that these fields are It sounds like this code mixes references and raw pointers in a subtle way -- maybe we'll end up declaring this correct, maybe not, it's certainly in a gray area. Ideally when there is aliasing like that, you just use raw pointers everywhere and avoid using references entirely, then the code is "obviously" correct. Mixing references and raw pointers to the same data should only be done with the utmost care and when absolutely necessary. Is there a reason this code cannot use raw pointers throughout? |
Looking at the code, this looks like an intrusive collection. Those are well-known to not be compatible with Rust references (unless you use shared references and |
Thank you, Ralf!
I mentioned "over concerned" because when I tried to simplify the unsafe list, I found stacked borrows handles this piece of code in a strange way. The existence of a null field somehow affects miri execution (the field does not involve any aliases). |
If you remove the field, |
That made sense! Never occurred to me it was the ZSTs. Thank you very much! |
Use queue-based `RwLock` on more platforms This switches over Windows 7, SGX and Xous to the queue-based `RwLock` implementation added in rust-lang#110211, thereby fixing rust-lang#121949 for Windows 7 and partially resolving rust-lang#114581 on SGX. TEEOS can't currently be switched because it doesn't have a good thread parking implementation. CC `@roblabla` `@raoulstrackx` `@xobs` Could you help me test this, please? r? `@ChrisDenton` the Windows stuff should be familiar to you
Rollup merge of rust-lang#123811 - joboet:queue_em_up, r=ChrisDenton Use queue-based `RwLock` on more platforms This switches over Windows 7, SGX and Xous to the queue-based `RwLock` implementation added in rust-lang#110211, thereby fixing rust-lang#121949 for Windows 7 and partially resolving rust-lang#114581 on SGX. TEEOS can't currently be switched because it doesn't have a good thread parking implementation. CC `@roblabla` `@raoulstrackx` `@xobs` Could you help me test this, please? r? `@ChrisDenton` the Windows stuff should be familiar to you
As of Aug 7, 2023, the unsafe list implementation in sgx waitqueue has a violation against Stacked Borrows.
Here is the playground link; executing it with miri produces an error.
I basically copy-pasted
library/std/src/sys/sgx/waitqueue/unsafe_list{.rs,/tests.rs}
into the playground link. I made a few minor modifications that should not affect the result:use crate::ptr::NonNull
touse std::ptr::NonNull
andrtassert!(...)
toassert!(...)
push_pop()
test inmain()
(other test cases exhibit the same error)It looks like an actual violation to me. Because
self.head_tail
is a mutable reborrow fromself.head_tail_entry
constructed ininit()
pop()
, the compiler retags (which is a Stacked Borrows rule) fields ofself
, invalidating any old references to its fields includingself.head_tail
.is_empty()
called bypop()
, we try to use the invalidated pointer.The last change to unsafe_list.rs was two years ago and it's a private module only used in
sys/sgx/waitqueue
, so the problem might not be that severe.Still, I wonder whether this is a false positive of miri, or can we confirm it's a Stacked Borrows/memory-safety violation.
The text was updated successfully, but these errors were encountered: