Skip to main content

starnix_core/vfs/buffers/
io_buffers.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::mm::{
6    MappingAccess, MemoryAccessorExt, NumberOfElementsRead, TaskMemoryAccessor, read_to_array,
7    read_to_object_as_bytes, read_to_vec,
8};
9use crate::task::{CurrentTask, Task};
10use smallvec::{SmallVec, smallvec};
11use starnix_types::user_buffer::{UserBuffer, UserBuffers};
12use starnix_uapi::errors::{ENOTSUP, Errno};
13use starnix_uapi::user_address::UserAddress;
14use starnix_uapi::{errno, error};
15use std::mem::MaybeUninit;
16use std::ops::{Deref, DerefMut};
17use zerocopy::FromBytes;
18
19/// The callback for `OutputBuffer::write_each`. The callback is passed the buffers to write to in
20/// order, and must return for each, how many bytes has been written.
21pub type OutputBufferCallback<'a> = dyn FnMut(&mut [MaybeUninit<u8>]) -> Result<usize, Errno> + 'a;
22
23fn slice_to_maybe_uninit(buffer: &[u8]) -> &[MaybeUninit<u8>] {
24    // SAFETY: &[u8] and &[MaybeUninit<u8>] have the same layout.
25    unsafe { std::slice::from_raw_parts(buffer.as_ptr() as *const MaybeUninit<u8>, buffer.len()) }
26}
27
28pub trait Iovec: Sized {
29    fn create(buffer: &UserBuffer) -> Self;
30}
31
32impl Iovec for syncio::zxio::iovec {
33    fn create(buffer: &UserBuffer) -> Self {
34        Self { iov_base: buffer.address.ptr() as *mut starnix_uapi::c_void, iov_len: buffer.length }
35    }
36}
37
38impl Iovec for syncio::zxio::zx_iovec {
39    fn create(buffer: &UserBuffer) -> Self {
40        Self { buffer: buffer.address.ptr() as *mut starnix_uapi::c_void, capacity: buffer.length }
41    }
42}
43
44impl Iovec for zx::sys::zx_iovec_t {
45    fn create(buffer: &UserBuffer) -> Self {
46        Self { buffer: buffer.address.ptr() as *const u8, capacity: buffer.length }
47    }
48}
49
50const IOVECS_IN_HEAP_THRESHOLD: usize = 5;
51
52/// Provides access to a slice of iovecs while retaining some reference.
53pub struct IovecsRef<'a, I: Sized> {
54    iovecs: SmallVec<[I; IOVECS_IN_HEAP_THRESHOLD]>,
55    _marker: std::marker::PhantomData<&'a I>,
56}
57
58impl<'a, I: Iovec> IovecsRef<'a, I> {
59    /// Returns the list of iovecs backing the buffer.
60    ///
61    /// Note that we use `IovecsRef<'_>` so that while `IovecsRef` is held,
62    /// no other methods may be called on the `Buffer` since `IovecsRef`
63    /// holds onto the mutable reference for the `Buffer`.
64    fn new<B: Buffer + ?Sized>(buf: &'a mut B) -> Result<Self, Errno> {
65        let mut iovecs = SmallVec::with_capacity(buf.segments_count()?);
66        buf.peek_each_segment(&mut |buffer| iovecs.push(I::create(buffer)))?;
67        Ok(IovecsRef { iovecs, _marker: Default::default() })
68    }
69}
70
71impl<I> Deref for IovecsRef<'_, I> {
72    type Target = [I];
73    fn deref(&self) -> &Self::Target {
74        &self.iovecs
75    }
76}
77
78impl<I> DerefMut for IovecsRef<'_, I> {
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        &mut self.iovecs
81    }
82}
83
84pub type PeekBufferSegmentsCallback<'a> = dyn FnMut(&UserBuffer) + 'a;
85
86/// A buffer.
87///
88/// Provides the common implementations for input and output buffers.
89pub trait Buffer: std::fmt::Debug {
90    /// Returns the number of segments, if the buffer supports I/O directly
91    /// to/from individual segments.
92    fn segments_count(&self) -> Result<usize, Errno>;
93
94    /// Calls the callback with each segment backing this buffer.
95    ///
96    /// Each segment can be read from (if this is an `InputBuffer`) or written to (if this is an
97    /// `OutputBuffer`) using either user copy routines or Zircon system calls.  If this is an
98    /// `OutputBuffer`, any damage caused by bad addresses will be restricted to user addresses.
99    fn peek_each_segment(
100        &mut self,
101        callback: &mut PeekBufferSegmentsCallback<'_>,
102    ) -> Result<(), Errno>;
103
104    /// Returns all the segments backing this `Buffer`.
105    ///
106    /// Note that we use `IovecsRef<'_>` so that while `IovecsRef` is held, no other methods may be
107    /// called on this `Buffer` since `IovecsRef` holds onto the mutable reference for this
108    /// `Buffer`.
109    ///
110    /// NOTE: The returned segments can only be accessed using user copy routines or Zircon system
111    /// calls (see the comment above for `peek_each_segment). The pointers returned are not _valid_
112    /// for any non-zero sized access (see Rust's std::ptr documentation).
113    fn peek_all_segments_as_iovecs(&mut self) -> Result<IovecsRef<'_, syncio::zxio::iovec>, Errno> {
114        IovecsRef::new(self)
115    }
116}
117
118/// Attempts to perform some I/O with the iovec segments of `Buffer`.
119///
120/// Returns `None` if the I/O can not be performed with iovecs (when unified
121/// aspaces is disabled or the `Buffer` does not support I/O on its segments
122/// directly).
123///
124/// NOTE: The segments can only be accessed using user copy routines or Zircon system calls (see the
125/// comment above for `peek_each_segment). The pointers returned are not _valid_ for any non-zero
126/// sized access (see Rust's std::ptr documentation).
127pub fn with_iovec_segments<B: Buffer + ?Sized, I: Iovec, T>(
128    data: &mut B,
129    f: impl FnOnce(&mut [I]) -> Result<T, Errno>,
130) -> Option<Result<T, Errno>> {
131    match IovecsRef::new(data) {
132        Ok(mut o) => Some(f(&mut o)),
133        Err(e) => {
134            if e.code == ENOTSUP {
135                None
136            } else {
137                Some(Err(e))
138            }
139        }
140    }
141}
142
143/// The OutputBuffer allows for writing bytes to a buffer.
144/// A single OutputBuffer will only write up to MAX_RW_COUNT bytes which is the maximum size of a
145/// single operation.
146pub trait OutputBuffer: Buffer {
147    /// Calls `callback` for each segment to write data for. `callback` must returns the number of
148    /// bytes actually written. When it returns less than the size of the input buffer, the write
149    /// is stopped.
150    ///
151    /// Returns the total number of bytes written.
152    fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno>;
153
154    /// Returns the number of bytes available to be written into the buffer.
155    fn available(&self) -> usize;
156
157    /// Returns the number of bytes already written into the buffer.
158    fn bytes_written(&self) -> usize;
159
160    /// Fills this buffer with zeros.
161    fn zero(&mut self) -> Result<usize, Errno>;
162
163    /// Advance the output buffer by `length` bytes.
164    ///
165    /// # Safety
166    ///
167    /// The caller must guarantee that the length bytes are initialized.
168    unsafe fn advance(&mut self, length: usize) -> Result<(), Errno>;
169
170    /// Write the content of `buffer` into this buffer. If this buffer is too small, the write will
171    /// be partial.
172    ///
173    /// Returns the number of bytes written in this buffer.
174    fn write(&mut self, buffer: &[u8]) -> Result<usize, Errno> {
175        let mut buffer = slice_to_maybe_uninit(buffer);
176
177        self.write_each(&mut move |data| {
178            let size = std::cmp::min(buffer.len(), data.len());
179            let (to_clone, remaining) = buffer.split_at(size);
180            data[0..size].clone_from_slice(to_clone);
181            buffer = remaining;
182            Ok(size)
183        })
184    }
185
186    /// Write the content of `buffer` into this buffer. It is an error to pass a buffer larger than
187    /// the number of bytes available in this buffer. In that case, the content of the buffer after
188    /// the operation is unspecified.
189    ///
190    /// In case of success, always returns `buffer.len()`.
191    fn write_all(&mut self, buffer: &[u8]) -> Result<usize, Errno> {
192        let size = self.write(buffer)?;
193        if size != buffer.len() { error!(EINVAL) } else { Ok(size) }
194    }
195
196    /// Write the content of the given `InputBuffer` into this buffer. The number of bytes written
197    /// will be the smallest between the number of bytes available in this buffer and in the
198    /// `InputBuffer`.
199    ///
200    /// Returns the number of bytes read and written.
201    fn write_buffer(&mut self, input: &mut dyn InputBuffer) -> Result<usize, Errno> {
202        self.write_each(&mut move |data| {
203            let size = std::cmp::min(data.len(), input.available());
204            input.read_exact(&mut data[0..size])
205        })
206    }
207}
208
209/// The callback for `InputBuffer::peek_each` and `InputBuffer::read_each`. The callback is passed
210/// the buffers to write to in order, and must return for each, how many bytes has been read.
211
212pub type InputBufferCallback<'a> = dyn FnMut(&[u8]) -> Result<usize, Errno> + 'a;
213
214/// The InputBuffer allows for reading bytes from a buffer.
215/// A single InputBuffer will only read up to MAX_RW_COUNT bytes which is the maximum size of a
216/// single operation.
217pub trait InputBuffer: Buffer {
218    /// Calls `callback` for each segment to peek data from. `callback` must returns the number of
219    /// bytes actually peeked. When it returns less than the size of the output buffer, the read
220    /// is stopped.
221    ///
222    /// Returns the total number of bytes peeked.
223    fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno>;
224
225    /// Returns the number of bytes available to be read from the buffer.
226    fn available(&self) -> usize;
227
228    /// Returns the number of bytes already read from the buffer.
229    fn bytes_read(&self) -> usize;
230
231    /// Clear the remaining content in the buffer. Returns the number of bytes swallowed. After this
232    /// method returns, `available()` will returns 0. This does not touch the data in the buffer.
233    fn drain(&mut self) -> usize;
234
235    /// Consumes `length` bytes of data from this buffer.
236    fn advance(&mut self, length: usize) -> Result<(), Errno>;
237
238    /// Calls `callback` for each segment to read data from. `callback` must returns the number of
239    /// bytes actually read. When it returns less than the size of the output buffer, the read
240    /// is stopped.
241    ///
242    /// Returns the total number of bytes read.
243    fn read_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
244        let length = self.peek_each(callback)?;
245        self.advance(length)?;
246        Ok(length)
247    }
248
249    /// Read all the remaining content in this buffer and returns it as a `Vec`.
250    fn read_all(&mut self) -> Result<Vec<u8>, Errno> {
251        let result = self.peek_all()?;
252        let drain_result = self.drain();
253        assert!(result.len() == drain_result);
254        Ok(result)
255    }
256
257    /// Peek all the remaining content in this buffer and returns it as a `Vec`.
258    fn peek_all(&mut self) -> Result<Vec<u8>, Errno> {
259        // SAFETY: self.peek returns the number of bytes read.
260        unsafe {
261            read_to_vec::<u8, _>(self.available(), |buf| self.peek(buf).map(NumberOfElementsRead))
262        }
263    }
264
265    /// Peeks the content of this buffer into `buffer`.
266    /// If `buffer` is too small, the read will be partial.
267    /// If `buffer` is too large, the remaining bytes will be left untouched.
268    ///
269    /// Returns the number of bytes read from this buffer.
270    fn peek(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
271        let mut index = 0;
272        self.peek_each(&mut move |data| {
273            let data = slice_to_maybe_uninit(data);
274            let size = std::cmp::min(buffer.len() - index, data.len());
275            buffer[index..index + size].clone_from_slice(&data[..size]);
276            index += size;
277            Ok(size)
278        })
279    }
280
281    /// Write the content of this buffer into `buffer`.
282    /// If `buffer` is too small, the read will be partial.
283    /// If `buffer` is too large, the remaining bytes will be left untouched.
284    ///
285    /// Returns the number of bytes read from this buffer.
286    fn read(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
287        let length = self.peek(buffer)?;
288        self.advance(length)?;
289        Ok(length)
290    }
291
292    /// Read the exact number of bytes required to fill buf.
293    ///
294    /// If `buffer` is larger than the number of available bytes, an error will be returned.
295    ///
296    /// In case of success, always returns `buffer.len()`.
297    fn read_exact(&mut self, buffer: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
298        let size = self.read(buffer)?;
299        if size != buffer.len() { error!(EINVAL) } else { Ok(size) }
300    }
301}
302
303pub trait InputBufferExt: InputBuffer {
304    /// Reads exactly `len` bytes into a returned `Vec`.
305    ///
306    /// Returns an error if `len` is larger than the number of available bytes.
307    fn read_to_vec_exact(&mut self, len: usize) -> Result<Vec<u8>, Errno> {
308        // SAFETY: `data.read_exact` returns `len` bytes on success.
309        unsafe { read_to_vec::<u8, _>(len, |buf| self.read_exact(buf).map(NumberOfElementsRead)) }
310    }
311
312    /// Reads up to `limit` bytes into a returned `Vec`.
313    fn read_to_vec_limited(&mut self, limit: usize) -> Result<Vec<u8>, Errno> {
314        // SAFETY: `data.read` returns the number of bytes read.
315        unsafe { read_to_vec::<u8, _>(limit, |buf| self.read(buf).map(NumberOfElementsRead)) }
316    }
317
318    /// Reads bytes into the array.
319    ///
320    /// Returns an error if `N` is larger than the number of available bytes.
321    fn read_to_array<const N: usize>(&mut self) -> Result<[u8; N], Errno> {
322        // SAFETY: `data.read_exact` returns `N` bytes on success.
323        unsafe {
324            read_to_array::<_, _, N>(|buf| {
325                self.read_exact(buf).map(|bytes_read| debug_assert_eq!(bytes_read, buf.len()))
326            })
327        }
328    }
329
330    /// Interprets the buffer as an object.
331    ///
332    /// Returns an error if the buffer does not have enough bytes to represent the
333    /// object.
334    fn read_to_object<T: FromBytes>(&mut self) -> Result<T, Errno> {
335        // SAFETY: the callback returns successfully only if the required number of
336        // bytes were read.
337        unsafe {
338            read_to_object_as_bytes(|buf| {
339                if self.read(buf)? != buf.len() { error!(EINVAL) } else { Ok(()) }
340            })
341        }
342    }
343}
344
345impl InputBufferExt for dyn InputBuffer + '_ {}
346impl<T: InputBuffer> InputBufferExt for T {}
347
348/// An OutputBuffer that write data to user space memory through a `TaskMemoryAccessor`.
349pub struct UserBuffersOutputBuffer<'a, M> {
350    mm: &'a M,
351    buffers: UserBuffers,
352    available: usize,
353    bytes_written: usize,
354}
355
356impl<'a, M> std::fmt::Debug for UserBuffersOutputBuffer<'a, M> {
357    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358        f.debug_struct("UserBuffersOutputBuffer")
359            .field("buffers", &self.buffers)
360            .field("available", &self.available)
361            .field("bytes_written", &self.bytes_written)
362            .finish()
363    }
364}
365
366impl<'a, M: TaskMemoryAccessor> UserBuffersOutputBuffer<'a, M> {
367    fn new_inner(mm: &'a M, mut buffers: UserBuffers) -> Result<Self, Errno> {
368        let available = UserBuffer::cap_buffers_to_max_rw_count(
369            mm.maximum_valid_address().ok_or_else(|| errno!(EINVAL))?,
370            &mut buffers,
371        )?;
372        // Reverse the buffers as the element will be removed as they are handled.
373        buffers.reverse();
374        Ok(Self { mm, buffers, available, bytes_written: 0 })
375    }
376
377    fn write_each_inner<B: AsRef<[u8]>, F: FnMut(usize) -> Result<B, Errno>>(
378        &mut self,
379        mut callback: F,
380    ) -> Result<usize, Errno> {
381        let mut bytes_written = 0;
382        while let Some(mut buffer) = self.buffers.pop() {
383            if buffer.is_null() {
384                continue;
385            }
386
387            let bytes = callback(buffer.length)?;
388            let bytes = bytes.as_ref();
389
390            bytes_written += self.mm.write_memory(buffer.address, bytes)?;
391            let bytes_len = bytes.len();
392            buffer.advance(bytes_len)?;
393            self.available -= bytes_len;
394            self.bytes_written += bytes_len;
395            if !buffer.is_empty() {
396                self.buffers.push(buffer);
397                break;
398            }
399        }
400        Ok(bytes_written)
401    }
402}
403
404impl<'a> UserBuffersOutputBuffer<'a, CurrentTask> {
405    pub fn unified_new(task: &'a CurrentTask, buffers: UserBuffers) -> Result<Self, Errno> {
406        Self::new_inner(task, buffers)
407    }
408
409    pub fn unified_new_at(
410        task: &'a CurrentTask,
411        address: UserAddress,
412        length: usize,
413    ) -> Result<Self, Errno> {
414        Self::unified_new(task, smallvec![UserBuffer { address, length }])
415    }
416}
417
418impl<'a> UserBuffersOutputBuffer<'a, Task> {
419    pub fn syscall_new(task: &'a Task, buffers: UserBuffers) -> Result<Self, Errno> {
420        Self::new_inner(task, buffers)
421    }
422}
423
424impl<'a, M: TaskMemoryAccessor> Buffer for UserBuffersOutputBuffer<'a, M> {
425    fn segments_count(&self) -> Result<usize, Errno> {
426        Ok(self.buffers.len())
427    }
428
429    fn peek_each_segment(
430        &mut self,
431        callback: &mut PeekBufferSegmentsCallback<'_>,
432    ) -> Result<(), Errno> {
433        // This `UserBuffersOutputBuffer` made sure that each segment only pointed
434        // to valid user-space address ranges on creation so each `buffer` is
435        // safe to write to.
436        // Callers (including `peek_all_segments_as_iovecs` and `with_iovec_segments`) pass these
437        // segments as `iovec` / `zx_iovec_t` slices directly to Zircon syscalls or `zxio` C FFI
438        // calls (bypassing `usercopy`), so lazy mappings must be mapped and writable private file
439        // mappings must be granted `ZX_VM_PERM_WRITE` (and marked `COW_MODIFIED`) in the user VMAR
440        // upfront. Note that this conservatively marks any writable private file mappings in
441        // `self.buffers` as `COW_MODIFIED` even if the subsequent `zx::Stream::readv` or `zxio`
442        // operation reads 0 bytes (e.g. at EOF), performs a short read that never reaches later
443        // `iovec` segments, or fails before writing.
444        self.mm.ensure_buffers_mapped_in_user_vmar(&self.buffers, MappingAccess::ForWriting)?;
445        for buffer in self.buffers.iter().rev() {
446            if buffer.is_null() {
447                continue;
448            }
449            callback(buffer)
450        }
451
452        Ok(())
453    }
454}
455
456impl<'a, M: TaskMemoryAccessor> OutputBuffer for UserBuffersOutputBuffer<'a, M> {
457    fn write(&mut self, mut bytes: &[u8]) -> Result<usize, Errno> {
458        let mut bytes_written = 0;
459        for buffer in self.buffers.iter().rev() {
460            if buffer.is_empty() {
461                continue;
462            }
463            if bytes.is_empty() {
464                break;
465            }
466            let len = std::cmp::min(buffer.length, bytes.len());
467            let (to_write, remaining) = bytes.split_at(len);
468            bytes_written += self.mm.write_memory(buffer.address, to_write)?;
469            bytes = remaining;
470            if len != buffer.length {
471                break;
472            }
473        }
474        // SAFETY: `bytes_written` bytes were initialized by `self.mm.write_memory` above.
475        unsafe {
476            self.advance(bytes_written)?;
477        }
478        Ok(bytes_written)
479    }
480
481    fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno> {
482        self.write_each_inner(|buflen| {
483            // SAFETY: `callback` returns the number of bytes read on success.
484            unsafe {
485                read_to_vec::<u8, _>(buflen, |buf| {
486                    let result = callback(buf)?;
487                    if result > buflen {
488                        return error!(EINVAL);
489                    }
490                    Ok(NumberOfElementsRead(result))
491                })
492            }
493        })
494    }
495
496    fn available(&self) -> usize {
497        self.available
498    }
499
500    fn bytes_written(&self) -> usize {
501        self.bytes_written
502    }
503
504    fn zero(&mut self) -> Result<usize, Errno> {
505        let mut bytes_written = 0;
506        while let Some(mut buffer) = self.buffers.pop() {
507            if buffer.is_null() {
508                continue;
509            }
510
511            let count = self.mm.zero(buffer.address, buffer.length)?;
512            buffer.advance(count)?;
513            bytes_written += count;
514
515            self.available -= count;
516            self.bytes_written += count;
517
518            if !buffer.is_empty() {
519                self.buffers.push(buffer);
520                break;
521            }
522        }
523
524        Ok(bytes_written)
525    }
526
527    unsafe fn advance(&mut self, mut length: usize) -> Result<(), Errno> {
528        if length > self.available() {
529            return error!(EINVAL);
530        }
531
532        while let Some(mut buffer) = self.buffers.pop() {
533            if buffer.is_null() {
534                continue;
535            }
536
537            let advance_by = std::cmp::min(length, buffer.length);
538            buffer.advance(advance_by)?;
539            self.available -= advance_by;
540            self.bytes_written += advance_by;
541            if !buffer.is_empty() {
542                self.buffers.push(buffer);
543                break;
544            }
545            length -= advance_by;
546        }
547
548        Ok(())
549    }
550}
551
552/// An InputBuffer that read data from user space memory through a `TaskMemoryAccessor`.
553pub struct UserBuffersInputBuffer<'a, M> {
554    mm: &'a M,
555    buffers: UserBuffers,
556    available: usize,
557    bytes_read: usize,
558}
559
560impl<'a, M> std::fmt::Debug for UserBuffersInputBuffer<'a, M> {
561    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
562        f.debug_struct("UserBuffersInputBuffer")
563            .field("buffers", &self.buffers)
564            .field("available", &self.available)
565            .field("bytes_read", &self.bytes_read)
566            .finish()
567    }
568}
569
570impl<'a, M: TaskMemoryAccessor> UserBuffersInputBuffer<'a, M> {
571    fn new_inner(mm: &'a M, mut buffers: UserBuffers) -> Result<Self, Errno> {
572        let available = UserBuffer::cap_buffers_to_max_rw_count(
573            mm.maximum_valid_address().ok_or_else(|| errno!(EINVAL))?,
574            &mut buffers,
575        )?;
576        // Reverse the buffers as the element will be removed as they are handled.
577        buffers.reverse();
578        Ok(Self { mm, buffers, available, bytes_read: 0 })
579    }
580
581    fn peek_each_inner<F: FnMut(&UserBuffer, usize) -> Result<usize, Errno>>(
582        &mut self,
583        mut callback: F,
584    ) -> Result<usize, Errno> {
585        let mut read = 0;
586        for buffer in self.buffers.iter().rev() {
587            if buffer.is_null() {
588                continue;
589            }
590
591            let result = callback(buffer, read)?;
592            if result > buffer.length {
593                return error!(EINVAL);
594            }
595            read += result;
596            if result != buffer.length {
597                break;
598            }
599        }
600        Ok(read)
601    }
602}
603
604impl<'a> UserBuffersInputBuffer<'a, CurrentTask> {
605    pub fn unified_new(task: &'a CurrentTask, buffers: UserBuffers) -> Result<Self, Errno> {
606        Self::new_inner(task, buffers)
607    }
608
609    pub fn unified_new_at(
610        task: &'a CurrentTask,
611        address: UserAddress,
612        length: usize,
613    ) -> Result<Self, Errno> {
614        Self::unified_new(task, smallvec![UserBuffer { address, length }])
615    }
616}
617
618impl<'a> UserBuffersInputBuffer<'a, Task> {
619    pub fn syscall_new(task: &'a Task, buffers: UserBuffers) -> Result<Self, Errno> {
620        Self::new_inner(task, buffers)
621    }
622}
623
624impl<'a, M: TaskMemoryAccessor> Buffer for UserBuffersInputBuffer<'a, M> {
625    fn segments_count(&self) -> Result<usize, Errno> {
626        Ok(self.buffers.iter().filter(|b| b.is_null()).count())
627    }
628
629    fn peek_each_segment(
630        &mut self,
631        callback: &mut PeekBufferSegmentsCallback<'_>,
632    ) -> Result<(), Errno> {
633        // This `UserBuffersInputBuffer` made sure that each segment only pointed
634        // to valid user-space address ranges on creation so each `buffer` is
635        // safe to read from.
636        // Callers (including `peek_all_segments_as_iovecs` and `with_iovec_segments`) pass these
637        // segments as `iovec` / `zx_iovec_t` slices directly to Zircon syscalls or `zxio` C FFI
638        // calls (bypassing `usercopy`), so lazy mappings must be mapped in the user VMAR upfront.
639        self.mm.ensure_buffers_mapped_in_user_vmar(&self.buffers, MappingAccess::ForReading)?;
640        for buffer in self.buffers.iter().rev() {
641            if buffer.is_null() {
642                continue;
643            }
644            callback(buffer)
645        }
646
647        Ok(())
648    }
649}
650
651impl<'a, M: TaskMemoryAccessor> InputBuffer for UserBuffersInputBuffer<'a, M> {
652    fn peek(&mut self, uninit_bytes: &mut [MaybeUninit<u8>]) -> Result<usize, Errno> {
653        self.peek_each_inner(|buffer, read_so_far| {
654            let read_to = &mut uninit_bytes[read_so_far..];
655            let read_count = std::cmp::min(buffer.length, read_to.len());
656            let read_to = &mut read_to[..read_count];
657            let read_bytes = self.mm.read_memory(buffer.address, read_to)?;
658            debug_assert_eq!(read_bytes.len(), read_count);
659            Ok(read_count)
660        })
661    }
662
663    fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
664        // Segments of up to `STACK_BUF_LEN` bytes are read into this stack buffer instead of a
665        // newly allocated `Vec`. It is 8-byte aligned for the same reason as the object in
666        // `read_to_object_as_bytes`: when the user address is 8-byte aligned, `hermetic_copy` can
667        // then use aligned word accesses on both sides.
668        const STACK_BUF_LEN: usize = 512;
669        #[repr(C, align(8))]
670        struct AlignedBuf([MaybeUninit<u8>; STACK_BUF_LEN]);
671        let mut stack_buf = AlignedBuf([MaybeUninit::uninit(); STACK_BUF_LEN]);
672        self.peek_each_inner(|buffer, _read_so_far| {
673            if buffer.length <= STACK_BUF_LEN {
674                let bytes =
675                    self.mm.read_memory(buffer.address, &mut stack_buf.0[..buffer.length])?;
676                callback(bytes)
677            } else {
678                let bytes = self.mm.read_memory_to_vec(buffer.address, buffer.length)?;
679                callback(&bytes)
680            }
681        })
682    }
683
684    fn drain(&mut self) -> usize {
685        let result = self.available;
686        self.bytes_read += self.available;
687        self.available = 0;
688        self.buffers.clear();
689        result
690    }
691
692    fn advance(&mut self, mut length: usize) -> Result<(), Errno> {
693        if length > self.available {
694            return error!(EINVAL);
695        }
696        self.available -= length;
697        self.bytes_read += length;
698        while let Some(mut buffer) = self.buffers.pop() {
699            if length < buffer.length {
700                buffer.advance(length)?;
701                self.buffers.push(buffer);
702                return Ok(());
703            }
704            length -= buffer.length;
705            if length == 0 {
706                return Ok(());
707            }
708        }
709        if length != 0 { error!(EINVAL) } else { Ok(()) }
710    }
711
712    fn available(&self) -> usize {
713        self.available
714    }
715    fn bytes_read(&self) -> usize {
716        self.bytes_read
717    }
718}
719
720/// An OutputBuffer that write data to an internal buffer.
721#[derive(Debug)]
722pub struct VecOutputBuffer {
723    buffer: Vec<u8>,
724    // Used to keep track of the requested capacity. `Vec::with_capacity` may
725    // allocate more than the requested capacity so we can't rely on
726    // `Vec::capacity` to return the expected capacity.
727    capacity: usize,
728}
729
730impl VecOutputBuffer {
731    pub fn new(capacity: usize) -> Self {
732        Self { buffer: Vec::with_capacity(capacity), capacity }
733    }
734
735    pub fn data(&self) -> &[u8] {
736        &self.buffer
737    }
738
739    pub fn reset(&mut self) {
740        self.buffer.clear()
741    }
742}
743
744impl From<VecOutputBuffer> for Vec<u8> {
745    fn from(data: VecOutputBuffer) -> Self {
746        data.buffer
747    }
748}
749
750impl Buffer for VecOutputBuffer {
751    fn segments_count(&self) -> Result<usize, Errno> {
752        Ok(1)
753    }
754
755    fn peek_each_segment(
756        &mut self,
757        callback: &mut PeekBufferSegmentsCallback<'_>,
758    ) -> Result<(), Errno> {
759        let current_len = self.buffer.len();
760        let buffer = &mut self.buffer.spare_capacity_mut()[..self.capacity - current_len];
761        callback(&UserBuffer {
762            address: UserAddress::from(buffer.as_mut_ptr() as u64),
763            length: buffer.len(),
764        });
765
766        Ok(())
767    }
768}
769
770impl OutputBuffer for VecOutputBuffer {
771    fn write_each(&mut self, callback: &mut OutputBufferCallback<'_>) -> Result<usize, Errno> {
772        let current_len = self.buffer.len();
773        let written =
774            callback(&mut self.buffer.spare_capacity_mut()[..self.capacity - current_len])?;
775        if current_len + written > self.capacity {
776            return error!(EINVAL);
777        }
778        // SAFETY: the vector is now initialized for an extra `written` bytes.
779        unsafe { self.buffer.set_len(current_len + written) }
780        Ok(written)
781    }
782
783    fn available(&self) -> usize {
784        self.capacity - self.buffer.len()
785    }
786
787    fn bytes_written(&self) -> usize {
788        self.buffer.len()
789    }
790
791    fn zero(&mut self) -> Result<usize, Errno> {
792        let zeroed = self.capacity - self.buffer.len();
793        self.buffer.resize(self.capacity, 0);
794        Ok(zeroed)
795    }
796
797    unsafe fn advance(&mut self, length: usize) -> Result<(), Errno> {
798        if length > self.available() {
799            return error!(EINVAL);
800        }
801
802        let current_len = self.buffer.len();
803        // SAFETY: The caller initialized the next `length` bytes, and the check above ensures
804        // `current_len + length <= self.capacity`. The buffer has at least `self.capacity` bytes
805        // of allocated capacity (see VecOutputBuffer::new).
806        unsafe { self.buffer.set_len(current_len + length) };
807        Ok(())
808    }
809}
810
811/// An InputBuffer that read data from an internal buffer.
812#[derive(Debug)]
813pub struct VecInputBuffer {
814    buffer: Vec<u8>,
815
816    // Invariant: `bytes_read <= buffer.len()` at all times.
817    bytes_read: usize,
818}
819
820impl VecInputBuffer {
821    pub fn new(buffer: &[u8]) -> Self {
822        Self { buffer: buffer.to_vec(), bytes_read: 0 }
823    }
824}
825
826impl From<Vec<u8>> for VecInputBuffer {
827    fn from(buffer: Vec<u8>) -> Self {
828        Self { buffer, bytes_read: 0 }
829    }
830}
831
832impl Buffer for VecInputBuffer {
833    fn segments_count(&self) -> Result<usize, Errno> {
834        Ok(1)
835    }
836
837    fn peek_each_segment(
838        &mut self,
839        callback: &mut PeekBufferSegmentsCallback<'_>,
840    ) -> Result<(), Errno> {
841        let buffer = &self.buffer[self.bytes_read..];
842        callback(&UserBuffer {
843            address: UserAddress::from(buffer.as_ptr() as u64),
844            length: buffer.len(),
845        });
846
847        Ok(())
848    }
849}
850
851impl InputBuffer for VecInputBuffer {
852    fn peek_each(&mut self, callback: &mut InputBufferCallback<'_>) -> Result<usize, Errno> {
853        let read = callback(&self.buffer[self.bytes_read..])?;
854        if self.bytes_read + read > self.buffer.len() {
855            return error!(EINVAL);
856        }
857        debug_assert!(self.bytes_read <= self.buffer.len());
858        Ok(read)
859    }
860    fn advance(&mut self, length: usize) -> Result<(), Errno> {
861        if length > self.buffer.len() {
862            return error!(EINVAL);
863        }
864        self.bytes_read += length;
865        debug_assert!(self.bytes_read <= self.buffer.len());
866        Ok(())
867    }
868    fn available(&self) -> usize {
869        self.buffer.len() - self.bytes_read
870    }
871    fn bytes_read(&self) -> usize {
872        self.bytes_read
873    }
874    fn drain(&mut self) -> usize {
875        let result = self.available();
876        self.bytes_read += result;
877        result
878    }
879}
880
881impl VecInputBuffer {
882    /// Read an object from userspace memory and increment the read position.
883    ///
884    /// Returns an error if there is not enough available bytes compared to the size of `T`.
885    pub fn read_object<T: FromBytes>(&mut self) -> Result<T, Errno> {
886        let size = std::mem::size_of::<T>();
887        let end = self.bytes_read + size;
888        if end > self.buffer.len() {
889            return error!(EINVAL);
890        }
891        let obj =
892            T::read_from_bytes(&self.buffer[self.bytes_read..end]).map_err(|_| errno!(EINVAL))?;
893        self.bytes_read = end;
894        debug_assert!(self.bytes_read <= self.buffer.len());
895        Ok(obj)
896    }
897}
898
899#[cfg(test)]
900mod tests {
901    use super::*;
902    use crate::mm::{MemoryAccessor as _, PAGE_SIZE};
903    use crate::testing::*;
904    use usercopy::slice_to_maybe_uninit_mut;
905
906    #[test]
907    fn test_data_input_buffer() {
908        let mut executor = fuchsia_async::TestExecutor::new();
909        executor.run_singlethreaded(async {
910            spawn_kernel_and_run(async |current_task| {
911                let page_size = *PAGE_SIZE;
912                let addr = map_memory(&current_task, UserAddress::default(), 64 * page_size);
913
914                let data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
915                let mm = current_task.deref();
916                mm.write_memory(addr, &data).expect("failed to write test data");
917
918                let input_iovec = smallvec![
919                    UserBuffer { address: addr, length: 25 },
920                    UserBuffer {
921                        address: (addr + 64usize).expect("Memory mapped OOB!"),
922                        length: 12
923                    },
924                ];
925
926                // Test incorrect callback.
927                {
928                    let mut input_buffer =
929                        UserBuffersInputBuffer::unified_new(&current_task, input_iovec.clone())
930                            .expect("UserBuffersInputBuffer");
931                    assert!(input_buffer.peek_each(&mut |data| Ok(data.len() + 1)).is_err());
932                }
933
934                // Test drain
935                {
936                    let mut input_buffer =
937                        UserBuffersInputBuffer::unified_new(&current_task, input_iovec.clone())
938                            .expect("UserBuffersInputBuffer");
939                    assert_eq!(input_buffer.available(), 37);
940                    assert_eq!(input_buffer.bytes_read(), 0);
941                    assert_eq!(input_buffer.drain(), 37);
942                    assert_eq!(input_buffer.available(), 0);
943                    assert_eq!(input_buffer.bytes_read(), 37);
944                }
945
946                // Test read_all
947                {
948                    let mut input_buffer =
949                        UserBuffersInputBuffer::unified_new(&current_task, input_iovec.clone())
950                            .expect("UserBuffersInputBuffer");
951                    assert_eq!(input_buffer.available(), 37);
952                    assert_eq!(input_buffer.bytes_read(), 0);
953                    let buffer = input_buffer.read_all().expect("read_all");
954                    assert_eq!(input_buffer.available(), 0);
955                    assert_eq!(input_buffer.bytes_read(), 37);
956                    assert_eq!(buffer.len(), 37);
957                    assert_eq!(&data[..25], &buffer[..25]);
958                    assert_eq!(&data[64..76], &buffer[25..37]);
959                }
960
961                // Test read
962                {
963                    let mut input_buffer =
964                        UserBuffersInputBuffer::unified_new(&current_task, input_iovec)
965                            .expect("UserBuffersInputBuffer");
966                    let mut buffer = [0; 50];
967                    assert_eq!(input_buffer.available(), 37);
968                    assert_eq!(input_buffer.bytes_read(), 0);
969                    assert_eq!(
970                        input_buffer
971                            .read_exact(slice_to_maybe_uninit_mut(&mut buffer[0..20]))
972                            .expect("read"),
973                        20
974                    );
975                    assert_eq!(input_buffer.available(), 17);
976                    assert_eq!(input_buffer.bytes_read(), 20);
977                    assert_eq!(
978                        input_buffer
979                            .read_exact(slice_to_maybe_uninit_mut(&mut buffer[20..37]))
980                            .expect("read"),
981                        17
982                    );
983                    assert!(
984                        input_buffer
985                            .read_exact(slice_to_maybe_uninit_mut(&mut buffer[37..]))
986                            .is_err()
987                    );
988                    assert_eq!(input_buffer.available(), 0);
989                    assert_eq!(input_buffer.bytes_read(), 37);
990                    assert_eq!(&data[..25], &buffer[..25]);
991                    assert_eq!(&data[64..76], &buffer[25..37]);
992                }
993            })
994            .await;
995        });
996    }
997
998    #[test]
999    fn test_data_output_buffer() {
1000        let mut executor = fuchsia_async::TestExecutor::new();
1001        executor.run_singlethreaded(async {
1002            spawn_kernel_and_run(async |current_task| {
1003                let page_size = *PAGE_SIZE;
1004                let addr = map_memory(&current_task, UserAddress::default(), 64 * page_size);
1005
1006                let output_iovec = smallvec![
1007                    UserBuffer { address: addr, length: 25 },
1008                    UserBuffer {
1009                        address: (addr + 64usize).expect("Memory was mapped OOB!"),
1010                        length: 12
1011                    },
1012                ];
1013
1014                let _mm = current_task.deref();
1015                let data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
1016
1017                // Test incorrect callback.
1018                {
1019                    let mut output_buffer =
1020                        UserBuffersOutputBuffer::unified_new(&current_task, output_iovec.clone())
1021                            .expect("UserBuffersOutputBuffer");
1022                    assert!(output_buffer.write_each(&mut |data| Ok(data.len() + 1)).is_err());
1023                }
1024
1025                // Test write
1026                {
1027                    let mut output_buffer =
1028                        UserBuffersOutputBuffer::unified_new(&current_task, output_iovec)
1029                            .expect("UserBuffersOutputBuffer");
1030                    assert_eq!(output_buffer.available(), 37);
1031                    assert_eq!(output_buffer.bytes_written(), 0);
1032                    assert_eq!(output_buffer.write_all(&data[0..20]).expect("write"), 20);
1033                    assert_eq!(output_buffer.available(), 17);
1034                    assert_eq!(output_buffer.bytes_written(), 20);
1035                    assert_eq!(output_buffer.write_all(&data[20..37]).expect("write"), 17);
1036                    assert_eq!(output_buffer.available(), 0);
1037                    assert_eq!(output_buffer.bytes_written(), 37);
1038                    assert!(output_buffer.write_all(&data[37..50]).is_err());
1039
1040                    let buffer = current_task
1041                        .read_memory_to_array::<128>(addr)
1042                        .expect("failed to write test data");
1043                    assert_eq!(&data[0..25], &buffer[0..25]);
1044                    assert_eq!(&data[25..37], &buffer[64..76]);
1045                }
1046            })
1047            .await;
1048        });
1049    }
1050
1051    #[::fuchsia::test]
1052    fn test_vec_input_buffer() {
1053        let mut input_buffer = VecInputBuffer::new(b"helloworld");
1054        assert!(input_buffer.peek_each(&mut |data| Ok(data.len() + 1)).is_err());
1055
1056        let mut input_buffer = VecInputBuffer::new(b"helloworld");
1057        assert_eq!(input_buffer.bytes_read(), 0);
1058        assert_eq!(input_buffer.available(), 10);
1059        assert_eq!(input_buffer.drain(), 10);
1060        assert_eq!(input_buffer.bytes_read(), 10);
1061        assert_eq!(input_buffer.available(), 0);
1062
1063        let mut input_buffer = VecInputBuffer::new(b"helloworld");
1064        assert_eq!(input_buffer.bytes_read(), 0);
1065        assert_eq!(input_buffer.available(), 10);
1066        assert_eq!(&input_buffer.read_all().expect("read_all"), b"helloworld");
1067        assert_eq!(input_buffer.bytes_read(), 10);
1068        assert_eq!(input_buffer.available(), 0);
1069
1070        let mut input_buffer = VecInputBuffer::new(b"helloworld");
1071        let mut buffer = [0; 5];
1072        assert_eq!(
1073            input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).expect("read"),
1074            5
1075        );
1076        assert_eq!(input_buffer.bytes_read(), 5);
1077        assert_eq!(input_buffer.available(), 5);
1078        assert_eq!(&buffer, b"hello");
1079        assert_eq!(
1080            input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).expect("read"),
1081            5
1082        );
1083        assert_eq!(input_buffer.bytes_read(), 10);
1084        assert_eq!(input_buffer.available(), 0);
1085        assert_eq!(&buffer, b"world");
1086        assert!(input_buffer.read_exact(slice_to_maybe_uninit_mut(&mut buffer)).is_err());
1087
1088        // Test read_object
1089        let mut input_buffer = VecInputBuffer::new(b"hello");
1090        assert_eq!(input_buffer.bytes_read(), 0);
1091        let buffer: [u8; 3] = input_buffer.read_object().expect("read_object");
1092        assert_eq!(&buffer, b"hel");
1093        assert_eq!(input_buffer.bytes_read(), 3);
1094        let buffer: [u8; 2] = input_buffer.read_object().expect("read_object");
1095        assert_eq!(&buffer, b"lo");
1096        assert_eq!(input_buffer.bytes_read(), 5);
1097        assert!(input_buffer.read_object::<[u8; 1]>().is_err());
1098        assert_eq!(input_buffer.bytes_read(), 5);
1099
1100        let mut input_buffer = VecInputBuffer::new(b"hello");
1101        assert_eq!(input_buffer.bytes_read(), 0);
1102        assert!(input_buffer.read_object::<[u8; 100]>().is_err());
1103        assert_eq!(input_buffer.bytes_read(), 0);
1104    }
1105
1106    #[::fuchsia::test]
1107    fn test_vec_output_buffer() {
1108        let mut output_buffer = VecOutputBuffer::new(10);
1109        assert!(output_buffer.write_each(&mut |data| Ok(data.len() + 1)).is_err());
1110        assert_eq!(output_buffer.bytes_written(), 0);
1111        assert_eq!(output_buffer.available(), 10);
1112        assert_eq!(output_buffer.write_all(b"hello").expect("write"), 5);
1113        assert_eq!(output_buffer.bytes_written(), 5);
1114        assert_eq!(output_buffer.available(), 5);
1115        assert_eq!(output_buffer.data(), b"hello");
1116        assert_eq!(output_buffer.write_all(b"world").expect("write"), 5);
1117        assert_eq!(output_buffer.bytes_written(), 10);
1118        assert_eq!(output_buffer.available(), 0);
1119        assert_eq!(output_buffer.data(), b"helloworld");
1120        assert!(output_buffer.write_all(b"foo").is_err());
1121        let data: Vec<u8> = output_buffer.into();
1122        assert_eq!(data, b"helloworld".to_vec());
1123    }
1124
1125    #[::fuchsia::test]
1126    fn test_vec_output_buffer_advance_preserves_capacity() {
1127        let mut output_buffer = VecOutputBuffer::new(10);
1128        output_buffer.buffer.spare_capacity_mut()[0].write(b'a');
1129        // SAFETY: The first byte of the spare capacity was initialized above.
1130        unsafe { output_buffer.advance(1).expect("advance") };
1131        assert_eq!(output_buffer.bytes_written(), 1);
1132        assert_eq!(output_buffer.available(), 9);
1133        assert_eq!(output_buffer.write_all(b"bcdefghij").expect("write"), 9);
1134        assert_eq!(output_buffer.data(), b"abcdefghij");
1135    }
1136
1137    #[::fuchsia::test]
1138    fn test_vec_write_buffer() {
1139        let mut input_buffer = VecInputBuffer::new(b"helloworld");
1140        let mut output_buffer = VecOutputBuffer::new(20);
1141        assert_eq!(output_buffer.write_buffer(&mut input_buffer).expect("write_buffer"), 10);
1142        assert_eq!(output_buffer.data(), b"helloworld");
1143    }
1144
1145    #[::fuchsia::test]
1146    async fn test_peek_each_segment_maps_lazy_mapping() {
1147        spawn_kernel_and_run(async |current_task| {
1148            let page_size = *PAGE_SIZE;
1149            let length = (2 * page_size) as usize;
1150            let addr = map_memory(&current_task, UserAddress::default(), 2 * page_size);
1151            let iovecs = smallvec![
1152                UserBuffer { address: addr, length: 25 },
1153                UserBuffer { address: (addr + 64usize).expect("in bounds"), length: 12 },
1154            ];
1155
1156            // Forking creates a child address space whose mappings are initially `MappingMode::Lazy`.
1157            {
1158                let child_task = current_task.clone_task_for_test(0, None);
1159                let mut input_buffer =
1160                    UserBuffersInputBuffer::unified_new(&child_task, iovecs.clone())
1161                        .expect("UserBuffersInputBuffer");
1162                let segments = input_buffer
1163                    .peek_all_segments_as_iovecs()
1164                    .expect("peek_all_segments_as_iovecs");
1165                assert_eq!(segments.len(), 2);
1166                assert!(
1167                    !child_task
1168                        .mm()
1169                        .unwrap()
1170                        .ensure_range_mapped_in_user_vmar(addr, Some(length))
1171                        .expect("ensure_range_mapped_in_user_vmar")
1172                );
1173            }
1174
1175            {
1176                let child_task = current_task.clone_task_for_test(0, None);
1177                let mut output_buffer = UserBuffersOutputBuffer::unified_new(&child_task, iovecs)
1178                    .expect("UserBuffersOutputBuffer");
1179                let segments = output_buffer
1180                    .peek_all_segments_as_iovecs()
1181                    .expect("peek_all_segments_as_iovecs");
1182                assert_eq!(segments.len(), 2);
1183                assert!(
1184                    !child_task
1185                        .mm()
1186                        .unwrap()
1187                        .ensure_range_mapped_in_user_vmar(addr, Some(length))
1188                        .expect("ensure_range_mapped_in_user_vmar")
1189                );
1190            }
1191        })
1192        .await;
1193    }
1194}