Panic-Surface Inventory
Scope: panic!, assert!, debug_assert!, .unwrap(), .expect(),
todo!, and unreachable! surfaces relevant to boot manifest loading, ELF
loading, SQE handling, params/result buffers, IPC, and future spawn inputs.
Classification terms:
trusted-internal: depends on kernel/shared-code invariants, static ABI layout, or host build/test code; not directly controlled by a service.boot-fatal: reached during boot/package setup before mutually untrusted services run. Bad platform/package state can halt the system.untrusted-input reachable: reachable from userspace-controlled SQEs, Cap’n Proto params/result buffers, IPC state, manifest/package data, or future spawn-controlled service/binary data.
Summary
No current panic!/assert!/unwrap()/expect() site found in the
kernel ring dispatch path directly consumes raw SQE fields or user
params/result-buffer pointers. Those paths mostly return CQE errors through
kernel/src/cap/ring.rs.
The remaining relevant surfaces are boot-fatal setup assumptions, scheduler
internal invariants that would become more exposed once untrusted spawn/lifecycle
inputs can create or destroy processes dynamically, one IPC queue invariant,
and a manifest validation .expect() guarded by a prior graph-validation call.
Manifest And Future Spawn Inputs
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/main.rs:308 run_init | MODULES.response().expect("no modules from bootloader") | Boot package/module table | boot-fatal | Missing Limine modules abort before manifest validation. |
capos-config/src/manifest.rs:328 validate_bootstrap_cap_sources | .expect("graph validation checked service exists") | Manifest service-source caps after validate_manifest_graph() | untrusted-input reachable, guarded | The call is safe only when callers preserve the current validation order in kernel/src/main.rs:346-351. Future spawn/package validation must not call this independently on unchecked manifests. |
kernel/src/main.rs:381 run_init | elf_cache.get(...).ok_or_else(...) | Manifest service binary reference | untrusted-input reachable, controlled error | Not a panic surface. Included because it is the future spawn shape to preserve: unknown or unparsed binaries return an error. |
kernel/src/main.rs:405 run_init | Process::new(...).map_err(...) | Manifest-spawned process creation | untrusted-input reachable, controlled error | Current boot path converts allocation/mapping failures into boot errors. Future ProcessSpawner should keep this shape instead of adding unwraps. |
kernel/src/cap/mod.rs:278 create_all_service_caps | unreachable!("kernel source resolved in pass 1") | Manifest cap source resolution | trusted-internal | Depends on the two-pass enum construction in the same function. Not directly controlled after pattern matching on CapSource::Kernel, but future dynamic grants should avoid relying on this internal sentinel. |
ELF Inputs
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/main.rs:202 load_elf | debug_assert!(stack_top % 16 == 0) | ELF load path | trusted-internal | Constant stack layout invariant, not ELF-controlled. |
kernel/src/main.rs:303 align_up | debug_assert!(align.is_power_of_two()) | TLS mapping from parsed ELF | trusted-internal | elf::parse rejects non-power-of-two TLS alignment; load_tls also caps the size before calling align_up. |
capos-lib/src/elf.rs parser | no runtime panic surfaces outside tests/Kani | Boot manifest ELF bytes; future spawn ELF bytes | untrusted-input reachable, controlled error | Parser uses checked offsets/ranges and returns Err(&'static str). Test-only assertions/unwraps are excluded from runtime classification. |
kernel/src/main.rs:167 load_elf | slice init_data[src_offset..] | Parsed ELF PT_LOAD file range | untrusted-input reachable, guarded | Not matched by the panic-token grep, but it is an index panic candidate if parser invariants are bypassed. elf::parse checks segment file ranges before load_elf. |
kernel/src/main.rs:290-293 load_tls | slice &init_data[init_start..init_end] | Parsed ELF TLS file range | untrusted-input reachable, guarded | Not matched by the panic-token grep, but it is an index panic candidate if parser invariants are bypassed. elf::parse checks TLS file bounds before load_tls. |
SQE And Params/Result Buffers
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/cap/ring.rs process_ring / dispatch_call / dispatch_recv / dispatch_return | no matched panic-like surfaces | Userspace SQEs, params, result buffers | untrusted-input reachable, controlled error | SQ corruption, unsupported fields/opcodes, oversized buffers, invalid user buffers, and CQ pressure return transport errors or defer consumption. |
capos-config/src/ring.rs:147-149 | const assert! layout checks | Shared ring ABI | trusted-internal | Compile-time ABI guard; not runtime input reachable. |
capos-config/src/capset.rs:53-55 | const assert! layout checks | Shared CapSet ABI | trusted-internal | Compile-time ABI/page-fit guard; not runtime input reachable. |
capos-lib/src/frame_bitmap.rs:87, capos-lib/src/frame_bitmap.rs:149 | .try_into().unwrap() on 8-byte bitmap windows | Frame allocation, including work triggered by manifest/process creation and capability methods | trusted-internal | Guarded by frame + 64 <= total or i + 64 <= to, assuming the caller-provided bitmap covers total_frames. Kernel constructs that bitmap at boot. |
IPC
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/cap/endpoint.rs:202 Endpoint::endpoint_call | pending_recvs.pop_front().unwrap() | Cross-process CALL delivered to pending RECV | untrusted-input reachable, guarded | Guarded by !inner.pending_recvs.is_empty() under the same lock. It is still on an IPC path driven by service SQEs, so S.8.4 should convert this to an explicit error/rollback path if panic-free IPC is required. |
kernel/src/cap/endpoint.rs:343-345 endpoint_restore_recv_front | unchecked push_front growth | IPC rollback path | untrusted-input reachable, non-panic today | VecDeque::push_front can allocate/panic if spare capacity assumptions are broken. Current pending recv queue is pre-reserved and bounded on normal insert; rollback paths should keep the bound explicit when hardened. |
Scheduler And Process Lifecycle
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/sched.rs:55 init_idle | Process::new_idle().expect(...) | Boot scheduler init | boot-fatal | Idle creation OOM/mapping failure panics before services run. |
kernel/src/sched.rs:206-211 block_current_on_cap_enter | current.expect, assert!, process-table expect | cap_enter(min_complete > 0) path | untrusted-input reachable, internal invariant | Userspace can request blocking, but these unwraps assert scheduler state, not user values. Future process lifecycle/spawn changes increase this exposure. |
kernel/src/sched.rs:252-264 capos_block_current_syscall | current.expect, idle assert!, table expect, panic! if not blocked | Blocking syscall continuation | untrusted-input reachable, internal invariant | Triggered after cap_enter chooses to block. User controls the request, but panic requires kernel state inconsistency. |
kernel/src/sched.rs:279, kernel/src/sched.rs:376 | run_queue references missing process expect | Scheduling after queue selection | trusted-internal now; future spawn/lifecycle sensitive | A stale run-queue PID panics. Dynamic spawn/exit must preserve run-queue/process-table invariants. |
kernel/src/sched.rs:407-422 exit_current | current.expect, idle assert!, remove(...).unwrap(), next-process unwrap() | Ambient exit syscall and future process exit | untrusted-input reachable, internal invariant | Any service can exit itself. Panic requires scheduler corruption or idle misuse, but future spawn/process APIs should harden this boundary. |
kernel/src/sched.rs:468-475 current_ring_and_caps | current.expect, process-table expect | cap_enter flush path | untrusted-input reachable, internal invariant | User can call cap_enter; panic requires no current process or missing table entry. |
kernel/src/sched.rs:493-517 start | initial run-queue expect, process-table unwrap, CR3 expect | Boot service start | boot-fatal | Manifest with zero services is rejected earlier, and process creation errors out; panics indicate scheduler/CR3 invariant breakage. |
kernel/src/arch/x86_64/context.rs:59-60 | CR3 expect("invalid CR3 from scheduler") | Timer interrupt scheduling | trusted-internal; future lifecycle sensitive | Scheduler should only return page-aligned CR3s from AddressSpace. |
Boot Platform And Memory Setup
| Location | Surface | Reachability | Classification | Notes |
|---|---|---|---|---|
kernel/src/main.rs:36 | assert!(BASE_REVISION.is_supported()) | Limine boot protocol | boot-fatal | Platform/bootloader contract check. |
kernel/src/main.rs:41-44 | memory-map and HHDM expect | Limine boot protocol | boot-fatal | Missing bootloader responses halt before untrusted services. |
kernel/src/main.rs:74 | cap::init().expect(...) | Kernel cap table bootstrap | boot-fatal | Fails on kernel-internal cap-table exhaustion. |
kernel/src/mem/frame.rs:39 | frame-bitmap region expect | Boot memory map | boot-fatal | Bad or too-small memory map halts. |
kernel/src/mem/frame.rs:115 | free_frame uses try_free_frame(...).expect(...) | Kernel-owned frame teardown | trusted-internal | Capability handlers use try_free_frame; this panic surface is for kernel-owned frames and rollback/Drop paths. |
kernel/src/mem/frame.rs:139 | assert!(offset != 0) | HHDM cache use before frame init | trusted-internal | Initialization-order invariant. |
kernel/src/mem/heap.rs:11 | heap allocation expect | Boot heap init | boot-fatal | Fails if the frame allocator cannot provide the fixed kernel heap. |
kernel/src/mem/paging.rs:32, kernel/src/mem/paging.rs:58, kernel/src/mem/paging.rs:70 | page-alignment .unwrap() / paging initialized assert! | Kernel frame/page-table internals | trusted-internal | frame::alloc_frame returns page-aligned addresses. |
kernel/src/mem/paging.rs:106, kernel/src/mem/paging.rs:189, kernel/src/mem/paging.rs:194 | kernel PML4/map remap expects | Kernel page-table setup | boot-fatal | Assumes kernel image is mapped in bootloader tables and enough frames exist. |
kernel/src/arch/x86_64/syscall.rs:49 | STAR selector expect | Syscall init | boot-fatal | GDT selector layout invariant. |
kernel/src/sched.rs:299, kernel/src/sched.rs:450, kernel/src/sched.rs:517 | CR3 expect("invalid CR3") | Context switch/exit/start | trusted-internal; future lifecycle sensitive | Scheduler should only carry page-aligned address-space roots. |
Audit Method
Candidate sites come from panic-token searches over runtime source plus manual review of nearby indexing and allocation paths on untrusted-input boundaries. The table excludes test-only assertions unless they enforce runtime ABI or layout contracts. Re-run the searches after code changes and classify new sites by reachability, not by token alone.
Search commands:
rg -n "\b(panic!|assert!|assert_eq!|assert_ne!|debug_assert!|debug_assert_eq!|debug_assert_ne!|unwrap\(|expect\(|todo!|unreachable!)" kernel capos-lib capos-config init demos tools schema system.cue Makefile docs -g '*.rs' -g '*.cue' -g '*.md' -g 'Makefile'
rg -n "\b(panic!|assert!|assert_eq!|assert_ne!|debug_assert!|debug_assert_eq!|debug_assert_ne!|unwrap\(|expect\(|todo!|unreachable!)" kernel/src capos-lib/src capos-config/src init/src demos/capos-demo-support/src demos/*/src tools/mkmanifest/src -g '*.rs'