blob: 05b7d57fdeccb19ad808a71f80cc3c86464f2261 [file] [view] [edit]
# IOBuffer
## Name
IOBuffer - Shared memory endpoint with asymmetric access control and disciplines
## Synopsis
An `IOBuffer` (IOB) is a peered Zircon kernel object designed for
high-throughput, low-latency communication and shared memory transports between
processes. It combines peered session management with multi-region
encapsulation, asymmetric access control, and kernel-mediated access
disciplines.
## Description
An `IOBuffer` always operates as a pair of endpoints (Endpoint 0 and Endpoint
1). It allows two processes to communicate by sharing multiple independent
memory regions (up to a maximum of 64, defined by `ZX_IOB_MAX_REGIONS`), each
configured with specific access permissions and behavior.
### Peered lifetime and signaling
Like Channels and Sockets, `IOBuffer` endpoints are peered.
- The endpoints control the lifetime of the backing memory regions.
- **Reference Tracking**: Active virtual memory mappings created from an
endpoint count as references alongside open handles to that endpoint.
- **Peer Closure**: When all references (both open handles and active virtual
memory mappings) to one endpoint close, the system asserts the
`ZX_IOB_PEER_CLOSED` signal on the opposing endpoint.
### Regions: Private vs. shared
An `IOBuffer` can encapsulate multiple memory regions:
- **Private Regions (`ZX_IOB_REGION_TYPE_PRIVATE`)**: Backed by a private
`VmObject` uniquely owned by the `IOBuffer` pair. Used for isolated,
point-to-point communication.
- **Shared Regions (`ZX_IOB_REGION_TYPE_SHARED`)** *(Experimental)*: Points to a
standalone `shared_region` object. Multiple independent `IOBuffer` pairs can
reference the same shared region, enabling many-to-one patterns (for example,
multiple client log writers sending data to a single reader).
### Asymmetric access control
You can configure each region with different permissions for Endpoint 0 and
Endpoint 1. Permissions include:
- **Direct Mapping**: Allows the process to map the region into its virtual
address space (VMAR) for direct read/write access.
- `ZX_IOB_ACCESS_EP0_CAN_MAP_READ` / `_WRITE`
- `ZX_IOB_ACCESS_EP1_CAN_MAP_READ` / `_WRITE`
- **Kernel-Mediated Access**: Restricts direct mapping, requiring all access to
go through kernel system calls (such as `zx_iob_writev`). This protects
against Time-of-Check to Time-of-Use (TOCTOU) attacks.
- `ZX_IOB_ACCESS_EP0_CAN_MEDIATED_READ` / `_WRITE`
- `ZX_IOB_ACCESS_EP1_CAN_MEDIATED_READ` / `_WRITE`
#### Effective rights and handle interaction
When validating a memory operation, the kernel intersects the region's access
permissions (logical AND) with the endpoint handle rights. Region-level
permissions cannot override handle-level permissions.
- **Map Operation**: The effective read/write rights are `uRn & hRn` and `uWn &
hWn` respectively, where `u` represents mapping permission and `h` represents
handle rights.
- **Mediated Operation**: The effective read/write rights are `kRn & hRn` and
`kWn & hWn` respectively, where `k` represents mediated permission and `h`
represents handle rights.
#### Mediated directionality vs. absolute permissions
Unlike direct mappings, kernel-mediated access operates in a logical/directional
sense rather than absolute hardware permissions. For example, a logical mediated
read operation (such as retrieving data from a ring buffer) may require the
kernel to write to bookkeeping structures in that same region under the hood.
The kernel permits such internal bookkeeping writes for read-only mediated
endpoints, because the kernel acts as the trusted mediator enforcing the logic.
### Memory access disciplines
Disciplines define the structured memory layout and behavior for
kernel-mediated operations within a region:
- **None (`ZX_IOB_DISCIPLINE_TYPE_NONE`)**: Free-form raw byte buffer. No
kernel-mediated operations.
- **ID Allocator (`ZX_IOB_DISCIPLINE_TYPE_ID_ALLOCATOR`)** *(Experimental)*: A
thread-safe structure mapping sized data blobs to sequentially allocated
numeric IDs. Useful for string interning in tracing.
- **Mediated Write Ring Buffer
(`ZX_IOB_DISCIPLINE_TYPE_MEDIATED_WRITE_RING_BUFFER`)** *(Experimental)*: A
circular ring buffer designed for concurrent, kernel-mediated writes by
multiple clients and a single userspace reader (for example, high-efficiency
system logging).
### Mapping via VMAR
The system maps IOBuffer regions into a VMAR via `zx_vmar_map_iob`. Only the
following VMAR options are supported:
- `ZX_VM_SPECIFIC`
- `ZX_VM_SPECIFIC_OVERWRITE`
- `ZX_VM_OFFSET_IS_UPPER_LIMIT`
- `ZX_VM_PERM_READ`
- `ZX_VM_PERM_WRITE`
- `ZX_VM_MAP_RANGE`
Any other VMAR options return `ZX_ERR_INVALID_ARGS`.
### Querying object properties and regions
IOBuffers support standard property queries via `zx_object_get_info`.
#### `ZX_INFO_IOB`
Returns information about the overall `IOBuffer` instance using `zx_iob_info_t`:
- ``options``: The options used at creation.
- ``region_count``: The number of memory regions encapsulated.
#### `ZX_INFO_IOB_REGIONS`
Returns information about each region as an array of `zx_iob_region_info_t`.
- **Access Bit Swapping**: When returned, the kernel swaps the access modifier
bits so that Endpoint 0 access bits reflect the rights of the endpoint handle
executing the query, and Endpoint 1 access bits reflect the peer's rights.
This allows endpoint-agnostic libraries to validate permissions dynamically.
#### `ZX_INFO_PROCESS_VMOS`
The kernel reports the memory objects backing private IOB regions under this
topic like standard VMOs. By default, backing VMOs share the name of the parent
`IOBuffer`.
## Rights
An `IOBuffer` handle has the following rights by default:
- `ZX_RIGHT_TRANSFER`
- `ZX_RIGHT_DUPLICATE`
- `ZX_RIGHT_WAIT`
- `ZX_RIGHT_INSPECT`
- `ZX_RIGHT_READ`
- `ZX_RIGHT_WRITE`
- `ZX_RIGHT_MAP`
- `ZX_RIGHT_SIGNAL`
- `ZX_RIGHT_SIGNAL_PEER`
- `ZX_RIGHT_GET_PROPERTY`
- `ZX_RIGHT_SET_PROPERTY`
## Properties
IOBuffers support the following properties:
- `ZX_PROP_NAME`: Used for diagnostics and attributing memory.
## Signals
The system can set the following signals for an `IOBuffer` endpoint:
- **ZX_IOB_PEER_CLOSED**: The peer endpoint closed (including all handles and
active mappings).
- **ZX_IOB_SHARED_REGION_UPDATED** *(Experimental)*: Raised when a shared region
has been updated by a mediated write.
## Syscalls
- [`zx_iob_create()`] - create a new peered IOBuffer pair
- [`zx_iob_create_shared_region()`] *(Experimental)* - create a standalone
shared region
- [`zx_iob_writev()`] - perform a kernel-mediated write to a region
- [`zx_iob_allocate_id()`] *(Experimental)* - allocate an ID in an ID Allocator
region
- [`zx_vmar_map_iob()`] - map an IOBuffer region into a VMAR
[`zx_iob_create()`]: /reference/syscalls/iob_create.md
[`zx_iob_create_shared_region()`]: /reference/syscalls/iob_create_shared_region.md
[`zx_iob_writev()`]: /reference/syscalls/iob_writev.md
[`zx_iob_allocate_id()`]: /reference/syscalls/iob_allocate_id.md
[`zx_vmar_map_iob()`]: /reference/syscalls/vmar_map_iob.md