Repository navigation
Remove toyos-untrusted; each decoder bounds the words it is handed - #965
Merged
Merged
Conversation
The owner decided (2026-10-21) to remove `toyos-untrusted` and keep every
boundary check. `Untrusted<T>` made a bound a review prompt, not a guarantee:
`map` let a closure narrow or copy the value out before the widening compare,
and a trivial bound (`at_most(u32::MAX)`, blockring's `opaque`) was an
unconditional exit. Every check it carried is one comparison, so each is now
written at the decode that makes the validated type, in plain integers,
compared before any narrowing.
- Kernel syscalls: the six register bounds (inventory, counters, partition
blocks, badge, TRACE_FLOOD, thread name) are direct comparisons of the
`u64` argument.
- Kernel virtio: `cap_subwindow` refuses with its own `CapWindow::NoBar` and
`PastBar`; `parse_used` takes the device's two words and stays the only way
to a `DescSlot`.
- Kernel xHCI: slot 0 is `checked_sub(1)`, not a wrap the bound happened to
catch.
- `toyos-virtio`: `UsedRefusal::Head { id, size }` and
`Written { head, len, writable }` carry the numbers, not a borrowed
`Refused`.
- `toyos-vdagent`: the event, port, chunk and data bounds are direct.
- `toyos-transport`: `Consumer::pop` returns the peer's `[u32; E]`;
`Run::decode` takes two words and leaves the bound to `Geometry::run`,
which already refuses every run past the arena, overflow included;
`Inflight::answer` takes the tag. The `rustc-dep-of-std` hop to the crate
goes.
- `toyos-blockring`: `Request::decode` and `Completion::decode` match on
constants and refuse reserved words directly; `opaque` and the client's
re-wrap of an already-decoded tag go.
The crate, its workspace membership, its `PUBLISHED` entry and std's
`[patch]`, sources and manifests for it are deleted, and the Rust fork's
`library/Cargo.lock` drops it (fork e1c5e93d342). The record of the crates
crates.io lacks now owes only `toyos-transport`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
Collaborator
Author
Review of #965 at 6699efb (round 1; diff against
|
Japabu
marked this pull request as ready for review
October 21, 2026 00:35
Japabu
enabled auto-merge
October 21, 2026 00:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #963 (the transport move). Its base is
wt/toyos-sdk-transport, so the diff shows this change alone.The owner decided (2026-10-21) to remove
toyos-untrustedand keep every boundary check.Untrusted<T>only made a bound something to notice in review; it guaranteed nothing:maplet a closure narrow the value, or copy it out, before the widening compare.at_most(u32::MAX), which is what blockring'sopaquedid.Every check it carried is a single comparison. Each now sits at the decode that produces the validated type, written in plain integers and compared before any narrowing. No replacement wrapper is introduced.
Site by site
kernel/src/syscall/dispatch.rs(inventory, counters, partition blocks, badge,TRACE_FLOOD, thread name)Untrusted::new(aN).at_most(B)if aN > B { EINVAL }, on theu64register;TRACE_FLOODis a match guard that falls through to the existingEINVALarmkernel/src/drivers/virtio.rscap_subwindow,parseindex/at_most→CapWindow::Refused(Refused)get(usize::from(bar)), thensize > window || offset > window - size, givingCapWindow::NoBar/PastBarwith their ownDisplaykernel/src/drivers/virtio.rsparse_usedUntrusted<u32>id/lenu32words; still the only way to aDescSlotkernel/src/drivers/xhci/mod.rsdevicemap(wrapping_sub(1)).index(..), sound only because the wrap missed the boundchecked_sub(1)?, then< dev_blockstoyos-virtiopoll_usedUsedRefusal::Head(Refused),Written { len: Refused }Head { id, size },Written { head, len, writable }; the Display keeps the prefix netstack's test matchestoyos-vdagentcontrol and streamindex/at_mostEvent::ALL.get,id >= max_nr_ports,usize::try_from(size)filtered byMAX_CHUNK/MAX_DATAtoyos-transportclamp(Untrusted),pop -> [Untrusted<u32>; E],Run::decode(Untrusted, Untrusted),Inflight::answer(Untrusted)clamp(u32);pop -> [u32; E], the peer's words for the protocol's decoder;Run::decode(u32, u32)leaves the bound toGeometry::run, which already refuses every run past the arena, overflow included (the<= slotspre-check was redundant);answer(u32)toyos-blockringRequest/Completion::decodeis(..)chains,opaque; the client re-wrapped an already-decoded tag to callanswermatchon the op constants, reserved words!= 0refused;opaqueand the re-wrap deletedAlso removed:
PUBLISHEDentry (build/sdkversion.rs), and its std sources, manifests and[patch]inbuild/sysroot.rs(plus that file's tests)rustc-dep-of-stdhop insdk/transport/Cargo.tomlkernel/pci/src/bar.rs,kernel/dma/Cargo.toml,kernel/src/mm/dma.rsandabuse_thread_name.rsThe #960 record
a-crate-new-to-the-published-set-...now owes onlytoyos-transport. Nothing is published to crates.io.Fork.
rust/library/Cargo.lockdropstoyos-untrustedin fork commit e1c5e93d342, pushed fast-forward to the fork'smain; this PR moves therustgitlink to it. The lockfile is what cargo itself resolves: after both image builds the file was byte-identical to the edit (cmp), and std compiledtoyos-transportwith notoyos-untrusted.Net: 36 files, +184/−682, most of it the deleted crate.
Checks
CONTROLS, e.g.no-clamp)cargo run -- --ci hostcargo run -- --build-only --arch <a>cargo test --test toyos-build -- nvme_disk_boots the_opening_exchange_with_qemus_agent_completes the_compositor_drives_the_virtio_gpu usb_keyboard_rollover console_image_bootsWhy these rows:
cap_subwindowandparse_used.nvme_disk_bootsreads its volume through blockring's decoders.toyos-virtio's used ring.usb_keyboard_rolloverbinds a device through the kernel xHCIdevice()lookup.The controls cover the checks whose removal would otherwise land unseen. Each mutation was applied, built, run red and then restored:
Inflight::answer's sequence checkWrittenboundas u16(the defect the crate was named for)MAX_DATAboundThe transport's cursor clamp already has its own loom control (
no-clamp), which the host suite runs.One host-suite run is red and is published as such:
mv, which brings back their old mtime, so cargo reused the mutated artifacts. The script nowtouches each restored file.UsedRefusal::Head's Display, and netstack'sa_used_head_past_the_table_ends_the_drivermatches its prefix. 6699efb restores the prefix, and the green run above is on that tree.Metal: requested, not run
T14 RUN REQUESTED (prepared with
--metal-readback, which touches no machine): two boots.pci_capability_walk, the kernel's crafted capability windows (15/15), andtrace_record_cost(TRACE_FLOOD's guard).abuse_thread_name(the thread-name refusal) andstream_handles(std streams over the transport).These are the kernel bounds and std paths that QEMU does not cover. request
Risks
mainis now at e1c5e93d342, while ToyOSmainstill pins 73f63e2441b until this lands. A build of the fork tip against today's ToyOSmainwould find the lockfile one entry short. Cargo re-resolves it unless--lockedis passed.main.🤖 Generated with Claude Code