Lines Matching +full:read +full:- +full:out
1 // SPDX-License-Identifier: GPL-2.0
20 /// A pointer to an area in userspace memory, which can be either read-only or read-write.
22 /// All methods on this struct are safe: attempting to read or write on bad addresses (either out of
27 /// presence of a race, the exact byte values read/written are unspecified but the operation is
28 /// well-defined. Kernelspace code should validate its copy of data after completing a read, and not
31 /// These APIs are designed to make it difficult to accidentally write TOCTOU (time-of-check to
32 /// time-of-use) bugs. Every time a memory location is read, the reader's position is advanced by
33 /// the read length and the next read will start from there. This helps prevent accidentally reading
39 /// If double-fetching a memory location is necessary for some reason, then that is done by creating
52 /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> {
53 /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer();
56 /// read.read_all(&mut buf, GFP_KERNEL)?;
67 /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
75 /// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> {
76 /// let read = UserSlice::new(uptr, len).reader();
79 /// read.read_all(&mut buf, GFP_KERNEL)?;
85 /// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> {
90 /// let read = UserSlice::new(uptr, len).reader();
93 /// read.read_all(&mut buf, GFP_KERNEL)?;
103 /// [`std::io`]: https://doc.rust-lang.org/std/io/index.html
118 /// attempt to read or write, not in the call to `UserSlice::new`.
120 /// Callers must be careful to avoid time-of-check-time-of-use (TOCTOU) issues. The simplest way
123 pub fn new(ptr: UserPtr, length: usize) -> Self { in new()
129 /// Fails with [`EFAULT`] if the read happens on a bad address.
130 pub fn read_all<A: Allocator>(self, buf: &mut Vec<u8, A>, flags: Flags) -> Result { in read_all()
135 pub fn reader(self) -> UserSliceReader { in reader()
143 pub fn writer(self) -> UserSliceWriter { in writer()
152 /// Usually when this is used, you will first read the data, and then overwrite it afterwards.
153 pub fn reader_writer(self) -> (UserSliceReader, UserSliceWriter) { in reader_writer()
169 /// Used to incrementally read from the user slice.
179 pub fn skip(&mut self, num_skip: usize) -> Result { in skip()
192 pub fn clone_reader(&self) -> UserSliceReader { in clone_reader()
199 /// Returns the number of bytes left to be read from this reader.
202 pub fn len(&self) -> usize { in len()
207 pub fn is_empty(&self) -> bool { in is_empty()
215 /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
216 /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error.
220 /// After a successful call to this method, all bytes in `out` are initialized.
221 pub fn read_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> Result { in read_raw()
222 let len = out.len(); in read_raw()
223 let out_ptr = out.as_mut_ptr().cast::<c_void>(); in read_raw()
234 self.length -= len; in read_raw()
240 /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
241 /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error.
242 pub fn read_slice(&mut self, out: &mut [u8]) -> Result { in read_slice()
244 // `out`. in read_slice()
245 let out = unsafe { &mut *(out as *mut [u8] as *mut [MaybeUninit<u8>]) }; in read_slice() localVariable
246 self.read_raw(out) in read_slice()
251 /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
253 pub fn read<T: FromBytes>(&mut self) -> Result<T> { in read() method
258 let mut out: MaybeUninit<T> = MaybeUninit::uninit(); in read() localVariable
259 // SAFETY: The local variable `out` is valid for writing `size_of::<T>()` bytes. in read()
263 // length is a compile-time constant. in read()
266 out.as_mut_ptr().cast::<c_void>(), in read()
275 self.length -= len; in read()
276 // SAFETY: The read above has initialized all bytes in `out`, and since `T` implements in read()
277 // `FromBytes`, any bit-pattern is a valid value for this type. in read()
278 Ok(unsafe { out.assume_init() }) in read()
283 /// Fails with [`EFAULT`] if the read happens on a bad address.
284 pub fn read_all<A: Allocator>(mut self, buf: &mut Vec<u8, A>, flags: Flags) -> Result { in read_all()
310 pub fn len(&self) -> usize { in len()
315 pub fn is_empty(&self) -> bool { in is_empty()
321 /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
324 pub fn write_slice(&mut self, data: &[u8]) -> Result { in write_slice()
330 // SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read in write_slice()
337 self.length -= len; in write_slice()
343 /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
346 pub fn write<T: AsBytes>(&mut self, value: &T) -> Result { in write()
356 // is a compile-time constant. in write()
368 self.length -= len; in write()