| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Slices to user space memory regions. |
| 4 | //! |
| 5 | //! C header: [`include/linux/uaccess.h`](srctree/include/linux/uaccess.h) |
| 6 | |
| 7 | use crate:: |
| 8 | , |
| 9 | bindings, |
| 10 | Coherent, |
| 11 | Result, |
| 12 | , |
| 13 | file, |
| 14 | *, |
| 15 | KnownSize, |
| 16 | , |
| 17 | ; |
| 18 | use ; |
| 19 | |
| 20 | /// A pointer into userspace. |
| 21 | /// |
| 22 | /// This is the Rust equivalent to C pointers tagged with `__user`. |
| 23 | |
| 24 | |
| 25 | ; |
| 26 | |
| 27 | |
| 28 | /// Create a `UserPtr` from an integer representing the userspace address. |
| 29 | |
| 30 | |
| 31 | Self |
| 32 | |
| 33 | |
| 34 | /// Create a `UserPtr` from a pointer representing the userspace address. |
| 35 | |
| 36 | |
| 37 | Self |
| 38 | |
| 39 | |
| 40 | /// Cast this userspace pointer to a raw const void pointer. |
| 41 | /// |
| 42 | /// It is up to the caller to use the returned pointer correctly. |
| 43 | |
| 44 | *const c_void |
| 45 | self.0 |
| 46 | |
| 47 | |
| 48 | /// Cast this userspace pointer to a raw mutable void pointer. |
| 49 | /// |
| 50 | /// It is up to the caller to use the returned pointer correctly. |
| 51 | |
| 52 | *mut c_void |
| 53 | self.0 |
| 54 | |
| 55 | |
| 56 | /// Increment this user pointer by `add` bytes. |
| 57 | /// |
| 58 | /// This addition is wrapping, so wrapping around the address space does not result in a panic |
| 59 | /// even if `CONFIG_RUST_OVERFLOW_CHECKS` is enabled. |
| 60 | |
| 61 | |
| 62 | UserPtr |
| 63 | |
| 64 | |
| 65 | |
| 66 | /// A pointer to an area in userspace memory, which can be either read-only or read-write. |
| 67 | /// |
| 68 | /// All methods on this struct are safe: attempting to read or write on bad addresses (either out of |
| 69 | /// the bound of the slice or unmapped addresses) will return [`EFAULT`]. Concurrent access, |
| 70 | /// *including data races to/from userspace memory*, is permitted, because fundamentally another |
| 71 | /// userspace thread/process could always be modifying memory at the same time (in the same way that |
| 72 | /// userspace Rust's [`std::io`] permits data races with the contents of files on disk). In the |
| 73 | /// presence of a race, the exact byte values read/written are unspecified but the operation is |
| 74 | /// well-defined. Kernelspace code should validate its copy of data after completing a read, and not |
| 75 | /// expect that multiple reads of the same address will return the same value. |
| 76 | /// |
| 77 | /// These APIs are designed to make it difficult to accidentally write TOCTOU (time-of-check to |
| 78 | /// time-of-use) bugs. Every time a memory location is read, the reader's position is advanced by |
| 79 | /// the read length and the next read will start from there. This helps prevent accidentally reading |
| 80 | /// the same location twice and causing a TOCTOU bug. |
| 81 | /// |
| 82 | /// Creating a [`UserSliceReader`] and/or [`UserSliceWriter`] consumes the `UserSlice`, helping |
| 83 | /// ensure that there aren't multiple readers or writers to the same location. |
| 84 | /// |
| 85 | /// If double-fetching a memory location is necessary for some reason, then that is done by creating |
| 86 | /// multiple readers to the same memory location, e.g. using [`clone_reader`]. |
| 87 | /// |
| 88 | /// # Examples |
| 89 | /// |
| 90 | /// Takes a region of userspace memory from the current process, and modify it by adding one to |
| 91 | /// every byte in the region. |
| 92 | /// |
| 93 | /// ```no_run |
| 94 | /// use kernel::ffi::c_void; |
| 95 | /// use kernel::uaccess::{UserPtr, UserSlice}; |
| 96 | /// |
| 97 | /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result { |
| 98 | /// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); |
| 99 | /// |
| 100 | /// let mut buf = KVec::new(); |
| 101 | /// read.read_all(&mut buf, GFP_KERNEL)?; |
| 102 | /// |
| 103 | /// for b in &mut buf { |
| 104 | /// *b = b.wrapping_add(1); |
| 105 | /// } |
| 106 | /// |
| 107 | /// write.write_slice(&buf)?; |
| 108 | /// Ok(()) |
| 109 | /// } |
| 110 | /// ``` |
| 111 | /// |
| 112 | /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug. |
| 113 | /// |
| 114 | /// ```no_run |
| 115 | /// use kernel::ffi::c_void; |
| 116 | /// use kernel::uaccess::{UserPtr, UserSlice}; |
| 117 | /// |
| 118 | /// /// Returns whether the data in this region is valid. |
| 119 | /// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> { |
| 120 | /// let read = UserSlice::new(uptr, len).reader(); |
| 121 | /// |
| 122 | /// let mut buf = KVec::new(); |
| 123 | /// read.read_all(&mut buf, GFP_KERNEL)?; |
| 124 | /// |
| 125 | /// todo!() |
| 126 | /// } |
| 127 | /// |
| 128 | /// /// Returns the bytes behind this user pointer if they are valid. |
| 129 | /// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> { |
| 130 | /// if !is_valid(uptr, len)? { |
| 131 | /// return Err(EINVAL); |
| 132 | /// } |
| 133 | /// |
| 134 | /// let read = UserSlice::new(uptr, len).reader(); |
| 135 | /// |
| 136 | /// let mut buf = KVec::new(); |
| 137 | /// read.read_all(&mut buf, GFP_KERNEL)?; |
| 138 | /// |
| 139 | /// // THIS IS A BUG! The bytes could have changed since we checked them. |
| 140 | /// // |
| 141 | /// // To avoid this kind of bug, don't call `UserSlice::new` multiple |
| 142 | /// // times with the same address. |
| 143 | /// Ok(buf) |
| 144 | /// } |
| 145 | /// ``` |
| 146 | /// |
| 147 | /// [`std::io`]: https://doc.rust-lang.org/std/io/index.html |
| 148 | /// [`clone_reader`]: UserSliceReader::clone_reader |
| 149 | |
| 150 | ptr: UserPtr, |
| 151 | length: usize, |
| 152 | |
| 153 | |
| 154 | |
| 155 | /// Constructs a user slice from a raw pointer and a length in bytes. |
| 156 | /// |
| 157 | /// Constructing a [`UserSlice`] performs no checks on the provided address and length, it can |
| 158 | /// safely be constructed inside a kernel thread with no current userspace process. Reads and |
| 159 | /// writes wrap the kernel APIs `copy_from_user` and `copy_to_user`, which check the memory map |
| 160 | /// of the current process and enforce that the address range is within the user range (no |
| 161 | /// additional calls to `access_ok` are needed). Validity of the pointer is checked when you |
| 162 | /// attempt to read or write, not in the call to `UserSlice::new`. |
| 163 | /// |
| 164 | /// Callers must be careful to avoid time-of-check-time-of-use (TOCTOU) issues. The simplest way |
| 165 | /// is to create a single instance of [`UserSlice`] per user memory block as it reads each byte |
| 166 | /// at most once. |
| 167 | |
| 168 | UserSlice |
| 169 | |
| 170 | |
| 171 | /// Reads the entirety of the user slice, appending it to the end of the provided buffer. |
| 172 | /// |
| 173 | /// Fails with [`EFAULT`] if the read happens on a bad address. |
| 174 | |
| 175 | self.reader.read_all |
| 176 | |
| 177 | |
| 178 | /// Constructs a [`UserSliceReader`]. |
| 179 | |
| 180 | UserSliceReader |
| 181 | ptr: self.ptr, |
| 182 | length: self.length, |
| 183 | |
| 184 | |
| 185 | |
| 186 | /// Constructs a [`UserSliceWriter`]. |
| 187 | |
| 188 | UserSliceWriter |
| 189 | ptr: self.ptr, |
| 190 | length: self.length, |
| 191 | |
| 192 | |
| 193 | |
| 194 | /// Constructs both a [`UserSliceReader`] and a [`UserSliceWriter`]. |
| 195 | /// |
| 196 | /// Usually when this is used, you will first read the data, and then overwrite it afterwards. |
| 197 | |
| 198 | |
| 199 | UserSliceReader |
| 200 | ptr: self.ptr, |
| 201 | length: self.length, |
| 202 | , |
| 203 | UserSliceWriter |
| 204 | ptr: self.ptr, |
| 205 | length: self.length, |
| 206 | , |
| 207 | |
| 208 | |
| 209 | |
| 210 | |
| 211 | /// A reader for [`UserSlice`]. |
| 212 | /// |
| 213 | /// Used to incrementally read from the user slice. |
| 214 | |
| 215 | ptr: UserPtr, |
| 216 | length: usize, |
| 217 | |
| 218 | |
| 219 | |
| 220 | /// Skip the provided number of bytes. |
| 221 | /// |
| 222 | /// Returns an error if skipping more than the length of the buffer. |
| 223 | |
| 224 | // Update `self.length` first since that's the fallible part of this operation. |
| 225 | self.length = self.length.checked_sub.ok_or?; |
| 226 | self.ptr = self.ptr.wrapping_byte_add; |
| 227 | Ok |
| 228 | |
| 229 | |
| 230 | /// Create a reader that can access the same range of data. |
| 231 | /// |
| 232 | /// Reading from the clone does not advance the current reader. |
| 233 | /// |
| 234 | /// The caller should take care to not introduce TOCTOU issues, as described in the |
| 235 | /// documentation for [`UserSlice`]. |
| 236 | |
| 237 | UserSliceReader |
| 238 | ptr: self.ptr, |
| 239 | length: self.length, |
| 240 | |
| 241 | |
| 242 | |
| 243 | /// Returns the number of bytes left to be read from this reader. |
| 244 | /// |
| 245 | /// Note that even reading less than this number of bytes may fail. |
| 246 | |
| 247 | self.length |
| 248 | |
| 249 | |
| 250 | /// Returns `true` if no data is available in the io buffer. |
| 251 | |
| 252 | self.length == 0 |
| 253 | |
| 254 | |
| 255 | /// Reads raw data from the user slice into a kernel buffer. |
| 256 | /// |
| 257 | /// For a version that uses `&mut [u8]`, please see [`UserSliceReader::read_slice`]. |
| 258 | /// |
| 259 | /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of |
| 260 | /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error. |
| 261 | /// |
| 262 | /// # Guarantees |
| 263 | /// |
| 264 | /// After a successful call to this method, all bytes in `out` are initialized. |
| 265 | |
| 266 | let len = out.len; |
| 267 | let out_ptr = out.as_mut_ptr.; |
| 268 | if len > self.length |
| 269 | return Err; |
| 270 | |
| 271 | // SAFETY: `out_ptr` points into a mutable slice of length `len`, so we may write |
| 272 | // that many bytes to it. |
| 273 | let res = unsafe ; |
| 274 | if res != 0 |
| 275 | return Err; |
| 276 | |
| 277 | self.ptr = self.ptr.wrapping_byte_add; |
| 278 | self.length -= len; |
| 279 | Ok |
| 280 | |
| 281 | |
| 282 | /// Reads raw data from the user slice into a kernel buffer. |
| 283 | /// |
| 284 | /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of |
| 285 | /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error. |
| 286 | |
| 287 | // SAFETY: The types are compatible and `read_raw` doesn't write uninitialized bytes to |
| 288 | // `out`. |
| 289 | let out = unsafe ; |
| 290 | self.read_raw |
| 291 | |
| 292 | |
| 293 | /// Reads raw data from the user slice into a kernel buffer partially. |
| 294 | /// |
| 295 | /// This is the same as [`Self::read_slice`] but considers the given `offset` into `out` and |
| 296 | /// truncates the read to the boundaries of `self` and `out`. |
| 297 | /// |
| 298 | /// On success, returns the number of bytes read. |
| 299 | |
| 300 | let end = offset.saturating_add.min; |
| 301 | |
| 302 | let Some = out.get_mut else |
| 303 | return Ok; |
| 304 | ; |
| 305 | |
| 306 | self.read_slice?; |
| 307 | Ok |
| 308 | |
| 309 | |
| 310 | /// Reads raw data from the user slice into a kernel buffer partially. |
| 311 | /// |
| 312 | /// This is the same as [`Self::read_slice_partial`] but updates the given [`file::Offset`] by |
| 313 | /// the number of bytes read. |
| 314 | /// |
| 315 | /// This is equivalent to C's `simple_write_to_buffer()`. |
| 316 | /// |
| 317 | /// On success, returns the number of bytes read. |
| 318 | |
| 319 | if offset.is_negative |
| 320 | return Err; |
| 321 | |
| 322 | |
| 323 | let Ok = .try_into else |
| 324 | return Ok; |
| 325 | ; |
| 326 | |
| 327 | let read = self.read_slice_partial?; |
| 328 | |
| 329 | // OVERFLOW: `offset + read <= data.len() <= isize::MAX <= Offset::MAX` |
| 330 | *offset += read as i64; |
| 331 | |
| 332 | Ok |
| 333 | |
| 334 | |
| 335 | /// Reads a value of the specified type. |
| 336 | /// |
| 337 | /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of |
| 338 | /// bounds of this [`UserSliceReader`]. |
| 339 | |
| 340 | let len = ; |
| 341 | if len > self.length |
| 342 | return Err; |
| 343 | |
| 344 | let mut out: = uninit; |
| 345 | // SAFETY: The local variable `out` is valid for writing `size_of::<T>()` bytes. |
| 346 | // |
| 347 | // By using the _copy_from_user variant, we skip the check_object_size check that verifies |
| 348 | // the kernel pointer. This mirrors the logic on the C side that skips the check when the |
| 349 | // length is a compile-time constant. |
| 350 | let res = unsafe |
| 351 | _copy_from_user |
| 352 | out.as_mut_ptr., |
| 353 | self.ptr.as_const_ptr, |
| 354 | len, |
| 355 | |
| 356 | ; |
| 357 | if res != 0 |
| 358 | return Err; |
| 359 | |
| 360 | self.ptr = self.ptr.wrapping_byte_add; |
| 361 | self.length -= len; |
| 362 | // SAFETY: The read above has initialized all bytes in `out`, and since `T` implements |
| 363 | // `FromBytes`, any bit-pattern is a valid value for this type. |
| 364 | Ok |
| 365 | |
| 366 | |
| 367 | /// Reads the entirety of the user slice, appending it to the end of the provided buffer. |
| 368 | /// |
| 369 | /// Fails with [`EFAULT`] if the read happens on a bad address. |
| 370 | |
| 371 | let len = self.length; |
| 372 | buf.reserve?; |
| 373 | |
| 374 | // The call to `reserve` was successful, so the spare capacity is at least `len` bytes long. |
| 375 | self.read_raw?; |
| 376 | |
| 377 | // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the |
| 378 | // vector have been initialized. |
| 379 | unsafe ; |
| 380 | Ok |
| 381 | |
| 382 | |
| 383 | /// Read a NUL-terminated string from userspace and return it. |
| 384 | /// |
| 385 | /// The string is read into `buf` and a NUL-terminator is added if the end of `buf` is reached. |
| 386 | /// Since there must be space to add a NUL-terminator, the buffer must not be empty. The |
| 387 | /// returned `&CStr` points into `buf`. |
| 388 | /// |
| 389 | /// Fails with [`EFAULT`] if the read happens on a bad address (some data may have been |
| 390 | /// copied). |
| 391 | |
| 392 | |
| 393 | if buf.is_empty |
| 394 | return Err; |
| 395 | |
| 396 | |
| 397 | // SAFETY: The types are compatible and `strncpy_from_user` doesn't write uninitialized |
| 398 | // bytes to `buf`. |
| 399 | let mut dst = unsafe ; |
| 400 | |
| 401 | // We never read more than `self.length` bytes. |
| 402 | if dst.len > self.length |
| 403 | dst = &mut dst; |
| 404 | |
| 405 | |
| 406 | let mut len = raw_strncpy_from_user?; |
| 407 | if len < dst.len |
| 408 | // Add one to include the NUL-terminator. |
| 409 | len += 1; |
| 410 | else if len < buf.len |
| 411 | // This implies that `len == dst.len() < buf.len()`. |
| 412 | // |
| 413 | // This means that we could not fill the entire buffer, but we had to stop reading |
| 414 | // because we hit the `self.length` limit of this `UserSliceReader`. Since we did not |
| 415 | // fill the buffer, we treat this case as if we tried to read past the `self.length` |
| 416 | // limit and received a page fault, which is consistent with other `UserSliceReader` |
| 417 | // methods that also return page faults when you exceed `self.length`. |
| 418 | return Err; |
| 419 | else |
| 420 | // This implies that `len == buf.len()`. |
| 421 | // |
| 422 | // This means that we filled the buffer exactly. In this case, we add a NUL-terminator |
| 423 | // and return it. Unlike the `len < dst.len()` branch, don't modify `len` because it |
| 424 | // already represents the length including the NUL-terminator. |
| 425 | // |
| 426 | // SAFETY: Due to the check at the beginning, the buffer is not empty. |
| 427 | unsafe ; |
| 428 | |
| 429 | |
| 430 | // This method consumes `self`, so it can only be called once, thus we do not need to |
| 431 | // update `self.length`. This sidesteps concerns such as whether `self.length` should be |
| 432 | // incremented by `len` or `len-1` in the `len == buf.len()` case. |
| 433 | |
| 434 | // SAFETY: There are two cases: |
| 435 | // * If we hit the `len < dst.len()` case, then `raw_strncpy_from_user` guarantees that |
| 436 | // this slice contains exactly one NUL byte at the end of the string. |
| 437 | // * Otherwise, `raw_strncpy_from_user` guarantees that the string contained no NUL bytes, |
| 438 | // and we have since added a NUL byte at the end. |
| 439 | Ok |
| 440 | |
| 441 | |
| 442 | |
| 443 | /// A writer for [`UserSlice`]. |
| 444 | /// |
| 445 | /// Used to incrementally write into the user slice. |
| 446 | |
| 447 | ptr: UserPtr, |
| 448 | length: usize, |
| 449 | |
| 450 | |
| 451 | |
| 452 | /// Returns the amount of space remaining in this buffer. |
| 453 | /// |
| 454 | /// Note that even writing less than this number of bytes may fail. |
| 455 | |
| 456 | self.length |
| 457 | |
| 458 | |
| 459 | /// Returns `true` if no more data can be written to this buffer. |
| 460 | |
| 461 | self.length == 0 |
| 462 | |
| 463 | |
| 464 | /// Low-level write from a raw pointer. |
| 465 | /// |
| 466 | /// # Safety |
| 467 | /// |
| 468 | /// The caller must ensure that `from` is valid for reads of `len` bytes. |
| 469 | unsafe |
| 470 | if len > self.length |
| 471 | return Err; |
| 472 | |
| 473 | |
| 474 | // SAFETY: Caller guarantees `from` is valid for `len` bytes (see this function's |
| 475 | // safety contract). |
| 476 | let res = unsafe ; |
| 477 | if res != 0 |
| 478 | return Err; |
| 479 | |
| 480 | self.ptr = self.ptr.wrapping_byte_add; |
| 481 | self.length -= len; |
| 482 | Ok |
| 483 | |
| 484 | |
| 485 | /// Writes raw data to this user pointer from a kernel buffer. |
| 486 | /// |
| 487 | /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of |
| 488 | /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even |
| 489 | /// if it returns an error. |
| 490 | |
| 491 | // SAFETY: `data` is a valid slice, so `data.as_ptr()` is valid for |
| 492 | // reading `data.len()` bytes. |
| 493 | unsafe |
| 494 | |
| 495 | |
| 496 | /// Writes raw data to this user pointer from a DMA coherent allocation. |
| 497 | /// |
| 498 | /// Copies `count` bytes from `alloc` starting from `offset` into this userspace slice. |
| 499 | /// |
| 500 | /// # Errors |
| 501 | /// |
| 502 | /// - [`EOVERFLOW`]: `offset + count` overflows. |
| 503 | /// - [`ERANGE`]: `offset + count` exceeds the size of `alloc`, or `count` exceeds the |
| 504 | /// size of the user-space buffer. |
| 505 | /// - [`EFAULT`]: the write hits a bad address or goes out of bounds of this |
| 506 | /// [`UserSliceWriter`]. |
| 507 | /// |
| 508 | /// This call may modify the associated userspace slice even if it returns an error. |
| 509 | /// |
| 510 | /// Note: The memory may be concurrently modified by hardware (e.g., DMA). In such cases, |
| 511 | /// the copied data may be inconsistent, but this does not cause undefined behavior. |
| 512 | /// |
| 513 | /// # Example |
| 514 | /// |
| 515 | /// Copy the first 256 bytes of a DMA coherent allocation into a userspace buffer: |
| 516 | /// |
| 517 | /// ```no_run |
| 518 | /// use kernel::uaccess::UserSliceWriter; |
| 519 | /// use kernel::dma::Coherent; |
| 520 | /// |
| 521 | /// fn copy_dma_to_user( |
| 522 | /// mut writer: UserSliceWriter, |
| 523 | /// alloc: &Coherent<[u8]>, |
| 524 | /// ) -> Result { |
| 525 | /// writer.write_dma(alloc, 0, 256) |
| 526 | /// } |
| 527 | /// ``` |
| 528 | Sized> |
| 529 | &mut self, |
| 530 | alloc: &, |
| 531 | offset: usize, |
| 532 | count: usize, |
| 533 | |
| 534 | let len = alloc.size; |
| 535 | if offset.checked_add.ok_or? > len |
| 536 | return Err; |
| 537 | |
| 538 | |
| 539 | if count > self.len |
| 540 | return Err; |
| 541 | |
| 542 | |
| 543 | // SAFETY: `as_ptr()` returns a valid pointer to a memory region of `count()` bytes, as |
| 544 | // guaranteed by the `Coherent` invariants. The check above ensures `offset + count <= len`. |
| 545 | let src_ptr = unsafe ; |
| 546 | |
| 547 | // Note: Use `write_raw` instead of `write_slice` because the allocation is coherent |
| 548 | // memory that hardware may modify (e.g., DMA); we cannot form a `&[u8]` slice over |
| 549 | // such volatile memory. |
| 550 | // |
| 551 | // SAFETY: `src_ptr` points into the allocation and is valid for `count` bytes (see above). |
| 552 | unsafe |
| 553 | |
| 554 | |
| 555 | /// Writes raw data to this user pointer from a kernel buffer partially. |
| 556 | /// |
| 557 | /// This is the same as [`Self::write_slice`] but considers the given `offset` into `data` and |
| 558 | /// truncates the write to the boundaries of `self` and `data`. |
| 559 | /// |
| 560 | /// On success, returns the number of bytes written. |
| 561 | |
| 562 | let end = offset.saturating_add.min; |
| 563 | |
| 564 | let Some = data.get else |
| 565 | return Ok; |
| 566 | ; |
| 567 | |
| 568 | self.write_slice?; |
| 569 | Ok |
| 570 | |
| 571 | |
| 572 | /// Writes raw data to this user pointer from a kernel buffer partially. |
| 573 | /// |
| 574 | /// This is the same as [`Self::write_slice_partial`] but updates the given [`file::Offset`] by |
| 575 | /// the number of bytes written. |
| 576 | /// |
| 577 | /// This is equivalent to C's `simple_read_from_buffer()`. |
| 578 | /// |
| 579 | /// On success, returns the number of bytes written. |
| 580 | |
| 581 | if offset.is_negative |
| 582 | return Err; |
| 583 | |
| 584 | |
| 585 | let Ok = .try_into else |
| 586 | return Ok; |
| 587 | ; |
| 588 | |
| 589 | let written = self.write_slice_partial?; |
| 590 | |
| 591 | // OVERFLOW: `offset + written <= data.len() <= isize::MAX <= Offset::MAX` |
| 592 | *offset += written as i64; |
| 593 | |
| 594 | Ok |
| 595 | |
| 596 | |
| 597 | /// Writes the provided Rust value to this userspace pointer. |
| 598 | /// |
| 599 | /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of |
| 600 | /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even |
| 601 | /// if it returns an error. |
| 602 | |
| 603 | let len = ; |
| 604 | if len > self.length |
| 605 | return Err; |
| 606 | |
| 607 | // SAFETY: The reference points to a value of type `T`, so it is valid for reading |
| 608 | // `size_of::<T>()` bytes. |
| 609 | // |
| 610 | // By using the _copy_to_user variant, we skip the check_object_size check that verifies the |
| 611 | // kernel pointer. This mirrors the logic on the C side that skips the check when the length |
| 612 | // is a compile-time constant. |
| 613 | let res = unsafe |
| 614 | _copy_to_user |
| 615 | self.ptr.as_mut_ptr, |
| 616 | from_ref., |
| 617 | len, |
| 618 | |
| 619 | ; |
| 620 | if res != 0 |
| 621 | return Err; |
| 622 | |
| 623 | self.ptr = self.ptr.wrapping_byte_add; |
| 624 | self.length -= len; |
| 625 | Ok |
| 626 | |
| 627 | |
| 628 | |
| 629 | /// Reads a nul-terminated string into `dst` and returns the length. |
| 630 | /// |
| 631 | /// This reads from userspace until a NUL byte is encountered, or until `dst.len()` bytes have been |
| 632 | /// read. Fails with [`EFAULT`] if a read happens on a bad address (some data may have been |
| 633 | /// copied). When the end of the buffer is encountered, no NUL byte is added, so the string is |
| 634 | /// *not* guaranteed to be NUL-terminated when `Ok(dst.len())` is returned. |
| 635 | /// |
| 636 | /// # Guarantees |
| 637 | /// |
| 638 | /// When this function returns `Ok(len)`, it is guaranteed that the first `len` bytes of `dst` are |
| 639 | /// initialized and non-zero. Furthermore, if `len < dst.len()`, then `dst[len]` is a NUL byte. |
| 640 | |
| 641 | |
| 642 | // CAST: Slice lengths are guaranteed to be `<= isize::MAX`. |
| 643 | let len = dst.len as isize; |
| 644 | |
| 645 | // SAFETY: `dst` is valid for writing `dst.len()` bytes. |
| 646 | let res = unsafe |
| 647 | strncpy_from_user |
| 648 | dst.as_mut_ptr., |
| 649 | src.as_const_ptr., |
| 650 | len, |
| 651 | |
| 652 | ; |
| 653 | |
| 654 | if res < 0 |
| 655 | return Err; |
| 656 | |
| 657 | |
| 658 | |
| 659 | assert!; |
| 660 | |
| 661 | // GUARANTEES: `strncpy_from_user` was successful, so `dst` has contents in accordance with the |
| 662 | // guarantees of this function. |
| 663 | Ok |
| 664 |