[BUG] Failed CSpace allocation consumes an identity before storage is reserved #12

Closed
opened 2026-09-14 14:29:11 +02:00 by erikinkinen · 0 comments
Owner

Summary

CSpace creation increments its finite identity allocator before reserving record storage. A heap-allocation failure consumes an identity despite returning no CSpace. The source also scans all live records to find each reusable ID, making repeated empty-space creation increasingly expensive as live population grows.

Reproduction

Compile the original Kernel release library at e6bea362f9199230bf84269b1a8da6bd8da6470d with its original pinned dependencies. In an independently owned host test process, initialize the root CSpace and create empty private spaces while rejecting actual allocation/reallocation requests only within each create operation. Detect the real vector growth boundary without assuming capacity. Restore normal allocation, create one more space and compare its identity with the last successful identity plus one.

The original regression executable uses a thread-local System allocator observer; assertions and output run after allocation rejection is disabled. It submits no IPC or privileged instruction. The retained control fails with actual ID 5 versus expected ID 4 after one rejected growth attempt.

Expected and actual behavior

Expected: failed storage reservation publishes no record and consumes no identity. Root protection, empty-only destruction and nonwrapping identity exhaustion remain intact. Reusing a destroyed record must not recover old capability slots.

Actual: the next-ID counter advances before fallible vector growth. The control returns KernelHeapExhausted, followed by successful creation with ID 5. The failed attempt to create ID 4 is not rolled back. No guest failure, unauthorized capability or observed ID-wrap event is attributed to this finding.

Environment and identity

Original signed Kernel e6bea362f9199230bf84269b1a8da6bd8da6470d; Rust 1.97.1; x86_64 Linux host; release library and original Git dependency objects. The fault control runs the actual CSpace object API in a separate process, with explicitly bounded command ownership. No dependency override is used.

Evidence and prior checks

The original control exits 101 with one failed test and clean process cleanup. The new implementation reserves before publishing a new ID, uses a vacant-entry chain for constant-time reuse, and validates emptiness and vacancy publication under the same table lock. Focused CSpace and allocation/lifetime tests pass; full formatting, strict Clippy, unit/doc, freestanding and native VM validation remains in progress.

A separate three-repetition host elapsed profile measures 32,768 create/destroy cycles at each retained population. Median reuse is 1.635981 ms at zero retained private spaces and 643.094176 ms at 32,768. Setup is measured separately. This identifies host scaling; it is not exclusive CPU time or a native guest performance result.

Allocator validation checkpoint — 14 September 2026: Signed Kernel feature ae0f3ab918abec71e809c3b4a68e54ec1c475e0d carries original signed maintenance ancestor 41b57a7a67e6fee71f5708b55ab386b72366b8d8. Both use the same CSpace allocator with their respective original dependency graphs. The feature tree equals the previously validated e5198f8f3ce0dbc1ee3658cdd21bf10f0beed63c tree. Strict development/release default/all checks pass: 613/637 units plus two standalone tests on the feature graph, 589/613 plus one standalone on maintenance, with three existing ignores. All eight feature and six maintenance freestanding builds pass without warnings. Kernel CI 536 and 537 pass with four complete logs, 643,867 bytes and zero warnings. The actual allocator rejection control fails the original signed library with next ID 5 instead of 4; the corrected test covers repeated failed growth, initialization failure and allocation-free reuse. ID exhaustion, duplicate destruction, occupied-record preservation and clean reuse pass. The same three-sample host profile reduces 32,768 reuse cycles at 32,768 retained spaces from 643.094176 ms to 1.172569 ms; host elapsed only, with no exclusive-CPU or guest timing claim. Signed Integration a869a81eb406a4f027a2b5db573b6330ca114d94 selects both final source graphs and passes all 159 helper suites plus strict 320/321-unit development/release default/all Rust matrices. The final ordinary Rootd IPC-framing VM passes in 45.832335 seconds and the native distinct-argument/lifetime VM passes in 13.026853 seconds, under unchanged exit/marker/deadline rules with empty QEMU stderr. These are host build-and-run durations. The ordinary image is 27,934,720 bytes, SHA256 2a187127696d569ae5c627d9c1d154ad53c024e98d9a181dbb6006790f01a0cc; the lifetime image is 2,142,208 bytes, SHA256 8fa4c7512a5916a51ba956b1e55c84ac2945c2580ff9556c99c27cbaa6e3321d. Its final image, ELF and EFI bytes equal the preceding validated feature-tree artifacts. Older full CI 1605/1606 is still running; new 1607/1608 is waiting. No full-catalog pass, realm implementation or full guest build is claimed.

Tracking

Owning audit #2 and Kernel PR 3. The owned invocation proposal #11 remains a separate design decision; this allocator correction does not select escrow storage or establish realm provisioning. Keep the issue open until the signed correction, strict matrices and relevant native/CI results are recorded.

## Summary CSpace creation increments its finite identity allocator before reserving record storage. A heap-allocation failure consumes an identity despite returning no CSpace. The source also scans all live records to find each reusable ID, making repeated empty-space creation increasingly expensive as live population grows. ## Reproduction Compile the original Kernel release library at `e6bea362f9199230bf84269b1a8da6bd8da6470d` with its original pinned dependencies. In an independently owned host test process, initialize the root CSpace and create empty private spaces while rejecting actual allocation/reallocation requests only within each create operation. Detect the real vector growth boundary without assuming capacity. Restore normal allocation, create one more space and compare its identity with the last successful identity plus one. The original regression executable uses a thread-local System allocator observer; assertions and output run after allocation rejection is disabled. It submits no IPC or privileged instruction. The retained control fails with actual ID 5 versus expected ID 4 after one rejected growth attempt. ## Expected and actual behavior Expected: failed storage reservation publishes no record and consumes no identity. Root protection, empty-only destruction and nonwrapping identity exhaustion remain intact. Reusing a destroyed record must not recover old capability slots. Actual: the next-ID counter advances before fallible vector growth. The control returns `KernelHeapExhausted`, followed by successful creation with ID 5. The failed attempt to create ID 4 is not rolled back. No guest failure, unauthorized capability or observed ID-wrap event is attributed to this finding. ## Environment and identity Original signed Kernel `e6bea362f9199230bf84269b1a8da6bd8da6470d`; Rust 1.97.1; x86_64 Linux host; release library and original Git dependency objects. The fault control runs the actual CSpace object API in a separate process, with explicitly bounded command ownership. No dependency override is used. ## Evidence and prior checks The original control exits 101 with one failed test and clean process cleanup. The new implementation reserves before publishing a new ID, uses a vacant-entry chain for constant-time reuse, and validates emptiness and vacancy publication under the same table lock. Focused CSpace and allocation/lifetime tests pass; full formatting, strict Clippy, unit/doc, freestanding and native VM validation remains in progress. A separate three-repetition host elapsed profile measures 32,768 create/destroy cycles at each retained population. Median reuse is 1.635981 ms at zero retained private spaces and 643.094176 ms at 32,768. Setup is measured separately. This identifies host scaling; it is not exclusive CPU time or a native guest performance result. Allocator validation checkpoint — 14 September 2026: Signed Kernel feature `ae0f3ab918abec71e809c3b4a68e54ec1c475e0d` carries original signed maintenance ancestor `41b57a7a67e6fee71f5708b55ab386b72366b8d8`. Both use the same CSpace allocator with their respective original dependency graphs. The feature tree equals the previously validated `e5198f8f3ce0dbc1ee3658cdd21bf10f0beed63c` tree. Strict development/release default/all checks pass: 613/637 units plus two standalone tests on the feature graph, 589/613 plus one standalone on maintenance, with three existing ignores. All eight feature and six maintenance freestanding builds pass without warnings. Kernel CI [536](https://git.erikinkinen.fi/erix/kernel/actions/runs/536) and [537](https://git.erikinkinen.fi/erix/kernel/actions/runs/537) pass with four complete logs, 643,867 bytes and zero warnings. The actual allocator rejection control fails the original signed library with next ID 5 instead of 4; the corrected test covers repeated failed growth, initialization failure and allocation-free reuse. ID exhaustion, duplicate destruction, occupied-record preservation and clean reuse pass. The same three-sample host profile reduces 32,768 reuse cycles at 32,768 retained spaces from 643.094176 ms to 1.172569 ms; host elapsed only, with no exclusive-CPU or guest timing claim. Signed Integration `a869a81eb406a4f027a2b5db573b6330ca114d94` selects both final source graphs and passes all 159 helper suites plus strict 320/321-unit development/release default/all Rust matrices. The final ordinary Rootd IPC-framing VM passes in 45.832335 seconds and the native distinct-argument/lifetime VM passes in 13.026853 seconds, under unchanged exit/marker/deadline rules with empty QEMU stderr. These are host build-and-run durations. The ordinary image is 27,934,720 bytes, SHA256 `2a187127696d569ae5c627d9c1d154ad53c024e98d9a181dbb6006790f01a0cc`; the lifetime image is 2,142,208 bytes, SHA256 `8fa4c7512a5916a51ba956b1e55c84ac2945c2580ff9556c99c27cbaa6e3321d`. Its final image, ELF and EFI bytes equal the preceding validated feature-tree artifacts. Older full CI [1605](https://git.erikinkinen.fi/erix/integration/actions/runs/1605)/[1606](https://git.erikinkinen.fi/erix/integration/actions/runs/1606) is still running; new [1607](https://git.erikinkinen.fi/erix/integration/actions/runs/1607)/[1608](https://git.erikinkinen.fi/erix/integration/actions/runs/1608) is waiting. No full-catalog pass, realm implementation or full guest build is claimed. ## Tracking Owning audit #2 and [Kernel PR 3](https://git.erikinkinen.fi/erix/kernel/pulls/3). The owned invocation proposal #11 remains a separate design decision; this allocator correction does not select escrow storage or establish realm provisioning. Keep the issue open until the signed correction, strict matrices and relevant native/CI results are recorded.
erikinkinen 2026-09-14 14:29:11 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
erix/kernel#12
No description provided.