Skip to content

Commit b172e3d

Browse files
committed
smoke: gsudo rides the vm disk's own convenience account, and the check grep reads to EOF
Two lap mechanics bugs the local laps caught, both in lanes the Oct 6 hardening commit touched but never got to run green. The hardening read: my first fix reached for a smoketest ssh lane on a false premise — the declared [user] never exists on a disk kuma vm builds. The vm installer writes its own /var/lib/kuma/user answer (the kuma convenience account, name and password kuma by design), and the converger's machine-state-wins rule unsets the baked declaration before sourcing it. Three laps of Permission denied with the hash verifiably baked were the shadowing making itself known. The lane is now no second lane at all: the key that got us in, plus sudo -S with the account's own password on stdin. gsudo keeps its stderr in a file beside the lap's dirs rather than inside one — the cleanup rm -rf's vm-smoke/$name on the way out, pass or fail, and evidence written there dies with the lap. The update --check grep: the check's answer names composed in its first line, then lists every moved package — hundreds when the Fedora backlog is deep. grep -q stops at the match, closes the pipe, kuma's next write dies with EPIPE, and pipefail fails the pipeline though the word was there. Captured, then grepped: a capture reads to EOF, nothing downstream can close early. Local lap: --boot niri, all good — hardening sysctls at the floor, kargs applied, the declared user yields to the installer's answer.
1 parent 709d62f commit b172e3d

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

‎scripts/smoke.sh‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,16 @@ smoke_image() {
488488
|| bad "lock doesn't reference the composed base tag"
489489
ok "lock records the composed base"
490490

491-
"$KUMA" --config "$file" update --check | grep -q 'composed' \
492-
|| bad "update --check doesn't explain composed-base updates"
491+
# Captured rather than piped: the check's answer names "composed"
492+
# in its first line and then lists every package the repos have
493+
# moved, hundreds of lines when Fedora's backlog is deep. `grep
494+
# -q` stops at the match and closes the pipe, kuma's next write
495+
# dies with EPIPE, and under pipefail the panic's exit status
496+
# fails this pipeline though the word it greps for was there.
497+
# A capture reads to EOF; nothing downstream can close early.
498+
checked=$("$KUMA" --config "$file" update --check 2>&1 || true)
499+
grep -q 'composed' <<<"$checked" \
500+
|| bad "update --check doesn't explain composed-base updates: $checked"
493501
ok "check explains recompose semantics"
494502
fi
495503
}
@@ -3257,6 +3265,22 @@ smoke_boot() {
32573265
# caller builds the command here and wants the guest to run it literally.
32583266
guest() { ssh "${ssh_opts[@]}" "$@" 2>/dev/null; }
32593267

3268+
# The privileged reads (the sysctl floor, the public zone) need root:
3269+
# since the 7.2.9 kernel (the 2026-10-08 :44 float) two of the floor's
3270+
# keys are root-only-readable outright (0600 nodes, EPERM on the
3271+
# read), so the unprivileged read is not an option. The escalation is
3272+
# no second ssh lane — `kuma vm` builds every disk with kuma in
3273+
# wheel, "name and password kuma" (main.rs build_disk: the smoke and
3274+
# `kuma vm --run` both speak to this account by name) — so the key
3275+
# that got us in plus sudo -S with that password on stdin covers
3276+
# every root read. gsudo keeps its own stderr in a file rather than
3277+
# guest's /dev/null: its callers compare stdout, and an empty read is
3278+
# identical whether ssh died or sudo balked — the file is what tells
3279+
# those apart. Beside the lap's dirs, not inside one: the cleanup
3280+
# rm -rf's vm-smoke/$name on the way out, pass or fail, and evidence
3281+
# written there dies with the lap that needs it.
3282+
gsudo() { ssh "${ssh_opts[@]}" "sudo -S -p '' $*" 2>>"vm-smoke/gsudo-$name.err" <<<"kuma"; }
3283+
32603284
echo " .. waiting for ssh on $port"
32613285
# 1800: a first boot here too - the qcow2 kuma vm builds recomposes
32623286
# the composed base before sshd starts (see the 1128 note).
@@ -3603,8 +3627,12 @@ for file in examples/*.toml; do
36033627
# bash, not the example's own shell: /usr/bin/fish is only in the
36043628
# desktop sets, and a declared shell emits a build-time `test -x`
36053629
# guard that would fail the minimal image. No password_hash, because
3606-
# nothing here logs in as this account; it asks the machine about it
3607-
# from the shell `kuma vm` already provides.
3630+
# on a disk `kuma vm` builds this account never exists at all — the
3631+
# installer's /var/lib/kuma/user answer (the kuma convenience
3632+
# account) shadows the declared user, by design — so there is no
3633+
# password to write down, and nothing here logs in as this account
3634+
# anyway; the boot probes ask the machine about the user from the
3635+
# shell `kuma vm` already provides.
36083636
if [ $BOOT -eq 1 ]; then
36093637
booted_file="vm-smoke/$name.toml"
36103638
mkdir -p vm-smoke

0 commit comments

Comments
 (0)