[BUG] Reused device-frame slots authorize protection of unrelated backing #27

Closed
opened 2026-09-22 04:31:30 +02:00 by erikinkinen · 0 comments
Owner

Summary

An existing ordinary DeviceFrame mapping used its original numeric capability slot as a protection-authority check. After that slot was dropped and reused for a disjoint device range, the old mapping could still accept a rights change through the unrelated current grant. The fixed Kernel requires the complete existing physical page to lie within the selected current device grant. This is an authority-consistency defect; the original reproduction establishes a metadata update, not a read/write privilege increase or a native exploit.

Reproduction

Five owned host controls ran once against original Kernel b8568c51c4f7b326223bcefb04c56270a6b60375, with production source unchanged and test source archived before correction. The command was cargo test --locked --no-default-features protection_restore_ -- --nocapture with warning-denied compilation. One passed and four failed. The DeviceFrame control maps an owned range RW, drops the source, reuses its exact local slot for a disjoint page and requests R on the original mapping. The unrelated current grant carries sufficient requested rights but no authority over that backing.

The other original failures describe planned protection-restoration and same-backing-alias feature gaps under the runtime memory design. They are not evidence of this bug. The original managed-frame object-reuse denial already passed. The introducing revision and last known passing revision for the DeviceFrame inconsistency are unknown.

Expected and actual behavior

The original DeviceFrame control returns Ok(()) instead of RootSlotPolicyViolation and changes the old mapping's rights while preserving its old physical page. The current unrelated range cannot authorize that change; the complete original mapping record must remain unchanged on refusal.

The correction checks actual managed allocation identity and complete range containment, or complete device-page containment, after current selected grant rights and mapping admission. It preserves managed/device/anonymous kind boundaries. Numeric position and cached descriptive mapping state confer no authority. Current exact-backing aliases may authorize no-access/R/RW/RX protection in active or inactive VSpaces under the separate feature contract; W^X, explicit READ and current VSpace MAP remain mandatory. Historic access ceilings and original-slot equality are removed.

Environment and identity

  • Fixed Kernel, coordinated Integration catalogs and manual, on feature/posix-compat, using original signed commit-pinned dependencies.
  • Rust 1.97.1; x86_64 host controls in default/all-feature and debug/release configurations.
  • Native lifetime image: one TCG CPU, original 60-second limit and original 200..264 caller window.
  • The native unrelated-device test uses two exclusively owned fixture pages, translated independently. It reuses an already disposed local slot, refuses both no-access and READ protection of the retained original page, and disposes all temporary grants.
  • The managed execution test uses a real allocator-selected page from canonical validated boot reservations and usable RAM. Allocator authority is removed before user entry; no heap address is treated as delegated RAM authority.

Evidence and prior checks

Nine added host controls cover the original observations, device range boundaries and overflow, managed/device separation, selected alias rights, active/inactive restoration and final mapping custody. Three older hint/lookup assertions are updated for the documented same-backing-alias and restoration behavior while retaining independent rights, identity, geometry and capacity guards. A new test initially used the read/write-only caller-buffer validator for EXECUTE; the corrected test uses the process-mapping validator. A redundant overflow-test mask caught by strict Clippy was simplified without changing inputs. All failures remain retained.

Four strict configurations pass 766 default / 790 all-feature tests, with three pre-existing ignored cases. Formatting, strict host/native Clippy, host/native private rustdoc and thirteen native builds pass without warnings.

The lifetime fixture passes fifteen actual managed-frame control calls and twenty-nine device/domain calls. Actual CPL3 instructions write a function, remove access, restore RX and execute it, restore RW to change its bytes, and execute the changed function under RX. A narrow READ/MAP alias cannot borrow WRITE or EXECUTE from the held full source; it restores READ after source disposal. Final alias disposal preserves readable mapping custody, and unmap restores the original leaf and returns allocated bytes to zero. Every earlier witness remains required before the new FRAME_PROTECTION_RIGHTS_OK marker and final completion.

All 172 Integration helpers pass. Three exact-source native executions pass four maintained lifetime/invocation/mapping/sparse contracts with their original limits. All fifteen selected signatures verify; each packaged Kernel matches exactly one retained original ELF after normal stripping. The ordinary exec-successor VM passes against the full 73-component graph and its original 120-second limit. Image warnings and QEMU stderr are absent. The manual passes 45 tests and 2,433 pages; all 450,954 word bounds and both changed rendered pages are reviewed, with zero final warnings or overflow.

Tracking

Fixed through Kernel PR 3, Integration PR 12 and Docs PR 4. The phase checklist retains complete authority cleanup, Process endpoint scope, independent hardware roots, measured performance improvement, external toolchain rebuilding and both complete EriX guest-build generations as open requirements. The separate older ext4 CI deadline failures remain unresolved; this correction does not establish their cause or fix.

Publication CI: Kernel 642/643 and Docs 1013/1014 pass. Each pair has four complete original logs: Kernel totals 790,650 bytes with 766/790 tests and zero warning candidates; Docs totals 775,150 bytes with 45 tests, 2,433 pages and zero final warnings or overflow. Retain the original 35/1/0 LaTeX warning convergence. Integration 1725/1726 remains queued and receives no completed CI acceptance. The separate older ext4 deadline report remains open.

## Summary An existing ordinary DeviceFrame mapping used its original numeric capability slot as a protection-authority check. After that slot was dropped and reused for a disjoint device range, the old mapping could still accept a rights change through the unrelated current grant. The [fixed Kernel](https://git.erikinkinen.fi/erix/kernel/commit/f5dd939c462de9d62f317ab7d29c21779cbe11c7) requires the complete existing physical page to lie within the selected current device grant. This is an authority-consistency defect; the original reproduction establishes a metadata update, not a read/write privilege increase or a native exploit. ## Reproduction Five owned host controls ran once against original Kernel `b8568c51c4f7b326223bcefb04c56270a6b60375`, with production source unchanged and test source archived before correction. The command was `cargo test --locked --no-default-features protection_restore_ -- --nocapture` with warning-denied compilation. One passed and four failed. The DeviceFrame control maps an owned range RW, drops the source, reuses its exact local slot for a disjoint page and requests R on the original mapping. The unrelated current grant carries sufficient requested rights but no authority over that backing. The other original failures describe planned protection-restoration and same-backing-alias feature gaps under [the runtime memory design](https://git.erikinkinen.fi/erix/kernel/issues/1). They are not evidence of this bug. The original managed-frame object-reuse denial already passed. The introducing revision and last known passing revision for the DeviceFrame inconsistency are unknown. ## Expected and actual behavior The original DeviceFrame control returns Ok(()) instead of RootSlotPolicyViolation and changes the old mapping's rights while preserving its old physical page. The current unrelated range cannot authorize that change; the complete original mapping record must remain unchanged on refusal. The correction checks actual managed allocation identity and complete range containment, or complete device-page containment, after current selected grant rights and mapping admission. It preserves managed/device/anonymous kind boundaries. Numeric position and cached descriptive mapping state confer no authority. Current exact-backing aliases may authorize no-access/R/RW/RX protection in active or inactive VSpaces under the separate feature contract; W^X, explicit READ and current VSpace MAP remain mandatory. Historic access ceilings and original-slot equality are removed. ## Environment and identity - Fixed [Kernel](https://git.erikinkinen.fi/erix/kernel/commit/f5dd939c462de9d62f317ab7d29c21779cbe11c7), coordinated [Integration catalogs](https://git.erikinkinen.fi/erix/integration/commit/8a9f865364656351fd8b12914e404a97b0be11c7) and [manual](https://git.erikinkinen.fi/erix/docs/commit/155b2a0cd2771cb45fa881155baf2cd0f1d1db27), on feature/posix-compat, using original signed commit-pinned dependencies. - Rust 1.97.1; x86_64 host controls in default/all-feature and debug/release configurations. - Native lifetime image: one TCG CPU, original 60-second limit and original 200..264 caller window. - The native unrelated-device test uses two exclusively owned fixture pages, translated independently. It reuses an already disposed local slot, refuses both no-access and READ protection of the retained original page, and disposes all temporary grants. - The managed execution test uses a real allocator-selected page from canonical validated boot reservations and usable RAM. Allocator authority is removed before user entry; no heap address is treated as delegated RAM authority. ## Evidence and prior checks Nine added host controls cover the original observations, device range boundaries and overflow, managed/device separation, selected alias rights, active/inactive restoration and final mapping custody. Three older hint/lookup assertions are updated for the documented same-backing-alias and restoration behavior while retaining independent rights, identity, geometry and capacity guards. A new test initially used the read/write-only caller-buffer validator for EXECUTE; the corrected test uses the process-mapping validator. A redundant overflow-test mask caught by strict Clippy was simplified without changing inputs. All failures remain retained. Four strict configurations pass 766 default / 790 all-feature tests, with three pre-existing ignored cases. Formatting, strict host/native Clippy, host/native private rustdoc and thirteen native builds pass without warnings. The lifetime fixture passes fifteen actual managed-frame control calls and twenty-nine device/domain calls. Actual CPL3 instructions write a function, remove access, restore RX and execute it, restore RW to change its bytes, and execute the changed function under RX. A narrow READ/MAP alias cannot borrow WRITE or EXECUTE from the held full source; it restores READ after source disposal. Final alias disposal preserves readable mapping custody, and unmap restores the original leaf and returns allocated bytes to zero. Every earlier witness remains required before the new FRAME_PROTECTION_RIGHTS_OK marker and final completion. All 172 Integration helpers pass. Three exact-source native executions pass four maintained lifetime/invocation/mapping/sparse contracts with their original limits. All fifteen selected signatures verify; each packaged Kernel matches exactly one retained original ELF after normal stripping. The ordinary exec-successor VM passes against the full 73-component graph and its original 120-second limit. Image warnings and QEMU stderr are absent. The manual passes 45 tests and 2,433 pages; all 450,954 word bounds and both changed rendered pages are reviewed, with zero final warnings or overflow. ## Tracking Fixed through [Kernel PR 3](https://git.erikinkinen.fi/erix/kernel/pulls/3), [Integration PR 12](https://git.erikinkinen.fi/erix/integration/pulls/12) and [Docs PR 4](https://git.erikinkinen.fi/erix/docs/pulls/4). [The phase checklist](https://git.erikinkinen.fi/erix/integration/issues/65) retains complete authority cleanup, Process endpoint scope, independent hardware roots, measured performance improvement, external toolchain rebuilding and both complete EriX guest-build generations as open requirements. The separate [older ext4 CI deadline failures](https://git.erikinkinen.fi/erix/integration/issues/73) remain unresolved; this correction does not establish their cause or fix. Publication CI: Kernel [642](https://git.erikinkinen.fi/erix/kernel/actions/runs/642)/[643](https://git.erikinkinen.fi/erix/kernel/actions/runs/643) and Docs [1013](https://git.erikinkinen.fi/erix/docs/actions/runs/1013)/[1014](https://git.erikinkinen.fi/erix/docs/actions/runs/1014) pass. Each pair has four complete original logs: Kernel totals 790,650 bytes with 766/790 tests and zero warning candidates; Docs totals 775,150 bytes with 45 tests, 2,433 pages and zero final warnings or overflow. Retain the original 35/1/0 LaTeX warning convergence. Integration [1725](https://git.erikinkinen.fi/erix/integration/actions/runs/1725)/[1726](https://git.erikinkinen.fi/erix/integration/actions/runs/1726) remains queued and receives no completed CI acceptance. The separate older ext4 deadline report remains open.
erikinkinen 2026-09-22 04:31:30 +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#27
No description provided.