CS/FN

Boundary log 06

Historical address / new Rust note

Rust: Encode the Boundary, Then Test the Unsafe Edge

An independent Rust design note for capability handles, ownership, unsafe adapters, and operating-system errors.

This exact address remains because Rust and systems pages still cite it. The text is new. This publication is not the original CloudABI project, does not maintain its Rust interfaces, and is not affiliated with its former contributors.

Rust can make a runtime boundary easier to express because ownership, borrowing, and concrete types can limit how a handle moves through a program. These language features do not create a security boundary by themselves. The operating system still enforces resource access, and unsafe or foreign-function code can break assumptions.

Use types to narrow intent

Wrap each supplied resource in a type that exposes only the operations the workload needs. A configuration reader does not need a general directory API. A status writer does not need read or seek methods. A connected service channel does not need an address-discovery interface.

The wrapper should own or borrow the underlying handle under a clear lifetime. Avoid global storage. If a handle can be cloned or transferred, make that operation visible and explain whether the copy carries the same authority.

Record these design points:

  1. authority represented by the type;
  2. constructor and validation path;
  3. permitted operations;
  4. clone, send, and share behavior;
  5. close and drop behavior;
  6. error mapping;
  7. unsafe or FFI surface; and
  8. negative tests.

The Rust standard library documentation is the primary reference for current standard types and platform notes. The Rust project site gives current project and release information. Store the toolchain version with test results.

Keep unsafe code at the adapter edge

Operating-system integration often needs FFI or low-level descriptor operations. Put this code in a small adapter module with a safe public contract. State every safety condition near the unsafe operation. Validate sizes, lifetimes, ownership transfer, alignment, and error results.

Do not treat a successful call as proof that the wrapper is sound. Test repeated close, interrupted calls, invalid values, concurrent access, partial I/O, and resource exhaustion. Use platform-specific tests for behavior that the standard library does not promise uniformly.

Preserve the original error

A library can provide a stable application error category while retaining the operating-system cause. Keep both. A broad “runtime failed” result makes boundary defects hard to distinguish from bad input or resource limits.

Avoid panics for expected external failures. A denied operation, closed handle, unavailable peer, or short write is part of the runtime contract. Return a result that the workload can handle and that tests can assert.

Test movement of authority

The most important tests are often about what code cannot obtain or retain. Confirm that a restricted component cannot construct a broader handle through a public API. Confirm that a borrowed handle does not outlive its owner. Confirm that background tasks stop using a resource before shutdown closes it.

The former CloudABI repository is historical context. This note does not reproduce its Rust guide. The current method is general: encode authority in narrow types, isolate the unsafe platform adapter, preserve diagnostic evidence, and test the negative edge where the language and operating system meet.