-
Notifications
You must be signed in to change notification settings - Fork 6
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 unsound Clone and undefined behavior in self-referential Buf variants #28
Fix unsound Clone and undefined behavior in self-referential Buf variants #28
Conversation
References &T to a type T are invalidated when T is moved, the same applies to core::ptr::Unique, which is used internally by Vec. This makes construction of a self-referential types such as TemplateBuf or ByteTemplateBuf a safety hazard. Introduce two helper types, aliasable::Bytes and aliasable::String, that store the raw parts of the original vectors, such that shared references can be obtained from the raw (non-unique) pointers. The implementation is inspired by the aliasable crate, which is was created for that very purpose. See the following blog post by Hrvoje Nikšić for more details: https://morestina.net/blog/1868/self-referential-types-for-fun-and-profit
Eep, thank you for reporting this and opening a PR! I can't believe I added that Maybe we can can use The last part of the fix is probably less likely to cause actual runtime problems. I still think they are super important to fix, but I would like to see if we can do it while reducing unsafe code instead of increasing it. I will yank the unsound versions once fixes are released! |
I merged the first three commits and released them as |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
I've opened #30 with a different approach to solving the aliasing problem. Rather than swapping The main motivation for the alternative approach is that it's less extra |
Merging without the last commit. Thanks again! This was a really important fix 😬 Released |
I'm not familiar enough with aliasing guarantees/details around Thank you for your quick action and your work in general too! |
TemplateBuf
andByteTemplate
are implemented as self-referential structs, but their current implementation is unsound and contains undefined behavior.According to my analysis the following issues exists:
Clone
implementations by the compiler are unsound, as they copy the static reference by value, causing all kinds of memory issues (panics due to memory issues caused my investigation.)String
orVec<u8>
will be dropped before the reference, this UB according to my understanding, as there will be dangling reference.String
andVec<u8>
are implemented usingcore::ptr::Unique
. As such all references to such a type, are invalidated, if such a type is moved. See Self-referential types for fun and profit by @hniksic for detailsThis PR tries to address these issues.
aliasable::String
andaliasable::Bytes
types instead of pulling in an extra dependency like thealiasable
crate.miri
. It passes but requires tree-borrows (MIRIFLAGS="-Zmiri-tree-borrows"
).