Skip to content

fix(enroll): sixth audit — umask, TOCTOU, atomic AGE_PUB, stale tmp cleanup, step-12 polish#178

Merged
mdheller merged 1 commit into
mainfrom
fix/enroll-sixth-audit
Jun 16, 2026
Merged

fix(enroll): sixth audit — umask, TOCTOU, atomic AGE_PUB, stale tmp cleanup, step-12 polish#178
mdheller merged 1 commit into
mainfrom
fix/enroll-sixth-audit

Conversation

@mdheller

Copy link
Copy Markdown
Member

Findings and fixes

# Finding Severity Fix
1 No umask 077 — all file creates expose a world-readable window before chmod 600 Medium umask 077 at line 16
2 TOCTOU on .env creation: cp then chmod 600 leaves plaintext passwords world-readable briefly Medium install -m 600 replaces cp+chmod
3 echo "${AGE_PUBKEY}" > "${AGE_PUB}" was the last non-atomic file write in the script Low printf > .tmp && mv
4 No stale .tmp cleanup at start of steps 8 and 9 for MINISIGN_CACHE_INFO.tmp / ENROLL_NIX.tmp Low rm -f *.tmp at each step start
5 info message in step 4 used docker compose (v2) but script requires docker-compose (v1) Low Align to docker-compose
6 sleep 10 in step 12 is a blind wait — may under-shoot on loaded systems Low 30s poll loop (systemctl is-active every 5s)
7 _SIG_TMP mktemp'd file in step 12 not covered by a trap — leaks on set -e exit Low trap "rm -f ..." EXIT + trap - EXIT after cleanup
8 nix copy URL inconsistent with docs (?compression=zstd missing) Cosmetic Three call sites updated

Test plan

  • bash -n scripts/enroll.sh — no syntax errors
  • Verify umask 077: add touch /tmp/enroll-test-$$; stat -c %a /tmp/enroll-test-$$ after umask line → 600
  • Verify .env file perms: stat -c %a ${COMPOSE_ENV} immediately after creation → 600
  • AGE_PUB.tmp disappears after step 3 (only age.pub remains)
  • Kill script mid-step 8 — confirm nix-cache-info.tmp cleaned on re-run
  • Step 12 poll: sourceos-syncd active within 30s on healthy system
  • Full physical M2 enroll run (P0 test)

…leanup, step-12 polish

- umask 077 at script top: all file creates default to owner-only
  permissions, closing the window between creation and explicit chmod 600
  for HW_CONFIG.tmp, ENROLL_NIX.tmp, and any future additions

- Use `install -m 600` instead of `cp` + `chmod 600` for COMPOSE_ENV:
  closes TOCTOU window where .env with plaintext passwords is
  world-readable from cp until the separate chmod call

- Atomic AGE_PUB write: `printf > .tmp && mv` consistent with all other
  file writes in the script; echo > AGE_PUB was the last non-atomic write

- Stale .tmp cleanup: add `rm -f` at start of steps 8 and 9 for
  MINISIGN_CACHE_INFO.tmp and ENROLL_NIX.tmp, matching the pattern
  established for HW_CONFIG.tmp in step 1

- docker-compose consistency: info message in step 4 used `docker compose`
  (v2 plugin syntax) while the script requires `docker-compose` (v1);
  operator copy-paste would fail if only v1 is installed

- Step 12 sleep 10 → 30s poll loop: `systemctl is-active` polled every 5s
  up to 30s; faster on the hot path, reliable on the slow path

- _SIG_TMP trap in step 12: mktemp'd file now covered by EXIT trap cleared
  after rm; prevents leak if set -e fires inside the minisig verify block

- nix copy URL: add ?compression=zstd to match katello-sourceos-setup.sh
  docs hint; all three call sites updated for consistency
@mdheller mdheller merged commit fdabab5 into main Jun 16, 2026
@mdheller mdheller deleted the fix/enroll-sixth-audit branch June 16, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant