You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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).
The text was updated successfully, but these errors were encountered:
Came here to file the same issue for process_vm_readv, which has the same problem. IANA expert, but I started digging into this when I was writing a wrapper for process_vm_readv, and found I couldn't have it take &[&mut [u8]] without using unsafe to coerce pointers, and doing so would cause Miri to flag it as UB.
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 somethinglibstd
already does, as well as the regularreadv
call insys::uio
. Additionally, we will need to change the implementations ofreadv
andpreadv
to takeas_mut_ptr
rather thanas_ptr
, since Rust allows no mutation from any pointer coming fromas_ptr
(which borrows &self immutably).The text was updated successfully, but these errors were encountered: