Repository navigation
tests: a syscall naming a claim's BAR copies through it, as the kernel's copy contract says - #1199
Conversation
…l's contract says #1150 made every user copy go through the process's own mapping and stated, at `user_ptr` and both `arch::uaccess`, that a window over device memory the process mapped is copied through, making only the accesses the process could make itself. `claim_bar_fault` still asserted the contract before it, a `BadAddress` for any buffer in a BAR, and has been red on aarch64's `virt_claim_lpi` since (run 42124293522 at 0b2dec6: the read answered `Ok(16)`). The owner ruled the contract stands: the buffer's address is the caller's own in that call, the copy holds no lock, and any fault in it is survived. `claim_bar_fault` now asserts that contract on AArch64: an aligned read into edu's two DMA address registers leaves the pipe's bytes in them, an aligned write from them carries those bytes, an unaligned copy either way answers `BadAddress` with the registers unchanged, and a futex word there is still refused. The markers the crash reports must not print go in after the copies. x86-64 had no row for it. `bar_map_again`, which already holds a mapped BAR of the virtio NIC on the suite's boot, carries it: a pipe write from `device_feature` carries what the holder's own byte loads read, and a pipe read into `device_feature_select` reaches the register. The manual's devices page states the rule in one line. The record `a-read-into-a-claims-bar-is-not-refused-on-aarch64` closes as a stale test; its durable rule is already at `user_ptr`'s header. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Run 42907842461 at 1710441: the copies passed, and the next ask read another `device_feature` word, because the check wrote zero to `device_feature_select` where firmware had left one. It now reads the byte first, has the kernel store the other value, and restores what was there. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Review r1 of #1199 at
|
…eck refuses a zero register The manual's line says what is copied and for whom. `bar_map_again`'s comparison with the holder's own byte loads asserts the low byte is not zero, so a copy of zeros cannot pass it; its comments each say their own access, and the select is "whatever the claim found there". Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
Orchestrator verification of the fix (f33b58e..e56cd25):
Landing. |
Problem
aarch64's
virt_claim_lpihas been red on main since #1150: itsclaim_bar_faultjob reads a pipe into its claim's mapped BAR and expectedBadAddress, and the kernel answersOk(16)(issues/a-read-into-a-claims-bar-is-not-refused-on-aarch64.md, run 42124293522 at 0b2dec6).Cause
Not a kernel regression. #1150 decided that a user copy goes through the process's own mapping and that a window over device memory the process mapped is copied through, making only the accesses the process itself could. It says so in its approved design note ("A user aperture (device memory) is copied through rather than refused") and at
kernel/src/user_ptr.rsand botharch::uaccessheaders.claim_bar_faultwas not updated and kept asserting the contract before it.Decision (the orchestrator's ruling)
The contract stands: every syscall buffer address is the caller's own in that call, the copy holds no lock, and the kernel survives any fault in it.
Checked before proceeding, by reading the code: no syscall copies to or from a user address the caller did not pass in that call.
user_ptr's privateView.Viewis made only through theSyscallContextcreated once per syscall indispatch.rs, and its windows carry that call's lifetime; no struct keeps one beyond it.Change
No kernel code changes.
claim_bar_fault(aarch64,virt_claim_lpi) asserts the stated contract on edu's two DMA address registers: an aligned 16-byte read leaves the pipe's bytes in them; an aligned write carries them back; an unaligned 8-byte copy either way answersBadAddresswith the registers unchanged (AArch64 Device memory); a futex wait and wake there are still refused. The crash-report markers go in after the copies.bar_map_again, which already maps the virtio NIC's common configuration on the suite's boot, carries it in about thirty lines, and that job runs under two rows,bar_map_againandbar_map_behind_a_bridge: a pipe write fromdevice_featureequals the holder's own byte loads, and a pipe read intodevice_feature_selectreaches the register, which is then put back. It needs the guest because it isrep movsbon a real function's registers.user_ptr's header.Checks
Evidence, round 2: https://github.com/ToyOSOrg/evidence/tree/ce2a88c6a5ffbbc1ebd3ad29481992809cb142a4/r2
Evidence, round 1: https://github.com/ToyOSOrg/evidence/tree/04c9b03533dff96d3dfba5b5737a94f022ee9717/r1
virt_claim_lpi(aarch64virt, emulated), run 42907842461bar_map_again(x86-64 q35), run 42907842461device_feature_selectwhere firmware had left one, so the next ask read another feature word. Fixed in f33b58e.bar_map_again, run 42909199077bar_map_againandbar_map_behind_a_bridge(x86-64 q35, the NIC on the root bus and behind a root port), run 42914728075cargo run -- --ci hoston macOSllvm::tests::the_caller_s_environment_reaches_neither_the_build_nor_the_key, already recorded inissues/the-llvm-environment-test-breaks-git-on-macos.mdand independent of this change, which touches no build code.virt_claim_lpiwas not rerun after 1710441: the later commits changebar_map_again.rs, a comment intests/toyos.rsand the manual's line, none of which its image or judgement carries. No host step builds the guest suite's binaries, and the latertests/toyos.rsedit is a doc comment, so the host result also holds for the head.Main's red run 42124293522 shows the old expectation was wrong for this kernel. That the new assertions can fail rests on inspection: a kernel on the old contract fails the first
Ok(16), one that stores through an unaligned access failsBadAddressor the register comparison, andbar_map_againasserts the register's low byte is not zero before comparing.Risks
bar_map_again's first failure showed that the row's register comparison rests ondevice_feature_selectbeing whatever firmware left (one, on the runner). That was so before this PR; the new check preserves it.🤖 Generated with Claude Code