-
Notifications
You must be signed in to change notification settings - Fork 703
Description
IoVec::from_mut_slice
uses as_ptr() to get a mutable pointer
Lines 227 to 233 in 5cd01a1
/// Create an `IoVec` from a mutable Rust slice. | |
pub fn from_mut_slice(buf: &'a mut [u8]) -> IoVec<&'a mut [u8]> { | |
IoVec(libc::iovec { | |
iov_base: buf.as_ptr() as *mut c_void, | |
iov_len: buf.len() as size_t, | |
}, PhantomData) | |
} |
This is unsound, because the pointer from as_ptr must never be written to
The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.
https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr
The code should use as_mut_ptr()
instead of as_ptr()
This problem may be occuring in other parts of the codebase too:
However, I don't know in which of these places the *mut
pointer is actually written to later.
vmsplice
is unsound too. It takes IoVec<&[u8]>
(immutable slice):
Lines 630 to 645 in 5cd01a1
pub fn vmsplice( | |
fd: RawFd, | |
iov: &[crate::sys::uio::IoVec<&[u8]>], | |
flags: SpliceFFlags | |
) -> Result<usize> | |
{ | |
let ret = unsafe { | |
libc::vmsplice( | |
fd, | |
iov.as_ptr() as *const libc::iovec, | |
iov.len(), | |
flags.bits(), | |
) | |
}; | |
Errno::result(ret).map(|r| r as usize) | |
} |
However, the vmsplice syscall can write to the given memory:
If fd is opened for reading, the vmsplice() system call fills nr_segs ranges of user memory described by iov from a pipe
https://man7.org/linux/man-pages/man2/vmsplice.2.html
Nix' vmsplice function should probably take IoVec<&mut [u8]>
instead