Repository navigation
Cowork image build 5 prep: #140 security-review lows, verify defaults - #141
Conversation
…criptor, the epoch scan's skips pinned by tests, verify requires the environment claim by default and refuses a stray /etc/gitconfig - dataroots.c make_plan_dir: after fchmod the bits are read back from the held descriptor and a mismatch is refused (as make_one does); a test build interposes fchmod to lie, and a ratchet mutant removes the check. - The epoch scan's leading-zero skip and the full-name digit check (i == n) are the lax side; a test now holds both (junk and non-canonical sibling names never make an epoch stale) and three ratchet mutants cover them. The two existing read-back mutants follow the new text. - verify.py: require_environment defaults to True in the library (callers that checked an older root pass False explicitly); a cpio that carries /etc/gitconfig of its own is refused, claim or no claim (the image ships the file only under /opt/winter/environment/base). - Guest source digests (init, relay, bootstrap helper) and the SDK pin ec91fe06 are already current; nothing moves.
|
What build 5 would do at this head. UNPINNED (expected, image.py exit 3, published, run turns red in the assert step): expectedArtifact (null), ownerLibrary.binarySha256 and launcher/executable digests changed by the SDK move (via check_expected), packageLockSha256 only if the lock differs. NOT expected: build_guest raises ValueError (not exit 3) when the freshly built init or winter-guest-relay binary differs from guest.programs.*.binarySha256 (dede7fd9..., eed3a8f2..., last set in dc995df). The production sources compiled since then changed (wmx.c, trusted_config.c, boot.c, init_linux.c, relay.c); if the binaries changed, build 5 dies before publishing anything, and verify.py (pinned_init from pins.json) would refuse too. These two digests come from a local build, not from the workflow: build.py --zig <pinned 0.14.1> --update-pins (test_build_digests_are_checked_against_a_real_build_when_zig_is_provided with WINTER_PINNED_ZIG checks it). No Zig is available to this lane (and a downloaded one may not be run), so it was not done here. Either run that before arming, or make build_guest/verify tolerate a binary mismatch as UNPINNED; say which. |
… (UNPINNED), a set pin that differs stays a hard failure - pins.json: guest.programs.init and winter-guest-relay binarySha256 are null (sourceSha256 unchanged): no Zig is run by a lane, so build 5 reports the digests it produces. - image.py: build_guest keeps refusing a set pin that differs and now refuses a missing key; guest_binary_problems reports each null with the built digest and the build ends at exit 3 with the other unpinned fields. check_startup uses the built init when the pin is null. - verify.py: a null init pin is read back only with allow_unpinned, against the init digest the root's own receipt claims (cpio and receipt must agree), and reports initPinned false; without the flag it is refused, a missing key is an error. - Tests for null, mismatch and missing key; test_binary_pin_mutants.py (11 mutants, "treat a mismatch as unpinned" among them).
|
Update at c0975e0: the init and relay binary pins are now an explicit null (UNPINNED, exit 3, the built digest reported); a set pin that differs is still a hard failure and a missing key is an error. Supersedes the caveat in my earlier comment. The workflow uploads a 14-day workflow artifact on exit 3 by design (never a release) and then turns the run red. |
…n guards held for empty and wrongly typed pins, relay read-back, digests.json carries both guest digests
- dataroots.c make_one reads the leaf's mode back from the descriptor (02770, setgid included) and refuses a mismatch; the test fchmod can lie on the root's own mode ("leaf") or add the sticky bit ("special"), which also kills the 07777 -> 0777 mask mutant; the plan-directory comment is now true.
- image.py / verify.py: an empty or wrongly typed binary pin ('', 0, false, a list) is a hard failure, never unpinned (tests; mutants for truthiness and `not pinned_init`). verify.py also holds the relay to its pin (null only with allow_unpinned, read back against the receipt; a set pin must be the relay in the cpio, 0555, and the receipt must say so).
- Comments: the top-level etc is a symlink into the base, so a literal etc/gitconfig cpio entry would write through it.
- image_build_report.py: digests.json carries relaySha256 and initPinned / relayPinned beside initSha256, and problems() names an unpinned or stale guest binary pin.
Folds the lows from the #140 security review and checks that the image build workflow at this head builds what integration holds. The workflow stays unarmed (REVIEWED_HEAD zeros, trigger branch cowork/guest-image-build-5 unchanged).
Build-5 caveat: the guest init/relay BINARY digests are checked hard by image.py build_guest (ValueError, not exit 3). See the PR comment.