-
Notifications
You must be signed in to change notification settings - Fork 724
Description
In Rust, attempting to obtain a mutable reference from an immutable reference is immediately Undefined Behavior, unless UnsafeCell is used, which includes mutable references behind immutable references (&&mut [u8], or in this case &[IoVec<&mut [u8]>]). This has also been extended to regular pointers, that originate from stack variables or regular references, now that Stacked Borrows is about to get integrated into the compiler. While the Rust compiler may not be ever able to detect UB within preadv, as syscalls are opaque and could have other side-effects, it could theoretically optimize subsequent code under the assumption that the iovec is aliased, and hence cannot allow its data to be mutated for the lifetime of the system call. Not only that, but this behavior could also change arbitrarily in future compiler versions.
What I suggest we do to fix this potential issue, is to revert the function signature in preadv (changed in #914) to take &mut [IoVec<&mut [u8]>], which is something libstd already does, as well as the regular readv call in sys::uio. Additionally, we will need to change the implementations of readv and preadv to take as_mut_ptr rather than as_ptr, since Rust allows no mutation from any pointer coming from as_ptr (which borrows &self immutably).