-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Document that str, slices, (more?) can't safely straddle allocation boundaries #62765
Comments
Agreed. I am pretty sure this already came up last year or before with another "slice concat" library that was found to be unsound, but I cannot find any trace of that right now. |
Pretty sure you mean this one 😄 |
@HeroicKatora I do, nice find! |
I don't suppose there's any way to mark that offsetof from one of the addresses could also be used to refer to a separately allocated object, e.g. |
@cramertj In principle, you can implement a fn cross_object_offset<T>(ptr: *const T, n: usize) -> *const T {
((ptr as usize) + n*mem::size_of::<T>()) as *const T
} However, there are some long-standing LLVM bugs in this area and with the LLVM model being as awfully imprecise as it is for UB, we can't really tell where the bug is. The good news though is that it seems like C++ is moving towards "pointer provenance does not propagate via integers", which would basically force LLVM to implement the semantics we want for the above operation. |
@RalfJung showed how to perform pointer arithmetic that crosses allocation boundaries. It's certainly possible to do this manually when handling raw pointers, but it's something that has to be done on every operation, you can't simply claim to LLVM that two separate allocations are actually the same. Therefore, fixing the safety issue that this issue is about would require us to implement all operations on slices/strings/etc. with |
#66111 did this for slices |
Well it did it in I didn't do anything for |
Slicing, indexing, and other safe operations on slices and strings pervasively use
<*T>::offset
and APIs built on top of it. These have the requirement thatSo if one allocates two pieces of memory and after proper checking miraculously finds they are directly adjacent, one can't safely construct a slice/str/etc. that spans both of these allocations. At least, one can't do very many things with the result it without causing UB from crossing the boundary between the allocations.
I couldn't find anything documenting this. It should be noted on the unsafe constructors (
from_raw_parts
etc.) at minimum. These already link tooffset
's documentation but only refer to its "no larger than isize::MAX" requirement, with no mention that the other requirements are also relevant.cc oberien/str-concat#8
cc @rust-lang/wg-unsafe-code-guidelines
(Similar issues apply to references-to-arrays and field accesses in aggregates, but this is due to the compiler's codegen for language primitives rather than due to standard library code, so it should go into the UCG and I believe we're more or less covering that already.)
The text was updated successfully, but these errors were encountered: