Skip to content

fix(#550): mkdir before chown -R in prepare_directories and reset_dashboard#574

Merged
VijitSingh97 merged 1 commit into
developfrom
claude/fix-550-chown-order
Jul 17, 2026
Merged

fix(#550): mkdir before chown -R in prepare_directories and reset_dashboard#574
VijitSingh97 merged 1 commit into
developfrom
claude/fix-550-chown-order

Conversation

@VijitSingh97

Copy link
Copy Markdown
Collaborator

Closes #550

Summary

prepare_directories and reset_dashboard ran sudo chown -R on a data-dir tree and then an unprivileged mkdir -p "$P2POOL_DIR/stats" inside it. For any operator uid ≠ 1000 (APP_UID/APP_GID are hardcoded), the mkdir gets EACCES and set -e aborts — in reset-dashboard the abort lands after the data wipe and before the containers come back up, stranding the install.

Both functions now match ensure_directories: every mkdir -p first, chown -R last. Pure reordering — no new helpers.

  • prepare_directories (pithead): mkdir -p "$P2POOL_DIR/stats" moved above the two chown -R lines.
  • reset_dashboard (pithead): mkdir -p "$p2pool_dir/stats" moved above the chown -R.

Other chown -R sites checked

Grepped pithead for every chown -R; besides the two fixed:

  • stack_restore (~line 1342): chown -R 100:101 "$TOR_DATA_DIR" — followed only by conditional ensure_owner calls on other trees; no unprivileged write into TOR_DATA_DIR after the chown. Clean.
  • ensure_owner (~line 2787): the reference-correct helper (ensure_directories calls it after all mkdirs). Clean.
  • provision_onion_client_auth (~line 2952): $run chown -R is the last op on $hs_dir, and every preceding write already uses the same $run (sudo) elevation. Clean.
  • CONTROL_DIR/CADDY_LOG_DIR/CLEARNET_STATE_DIR in prepare_control_dirs are sibling trees under data/, not inside any chowned dir. Clean.

Tests (tier 1, tests/stack/run.sh)

New ordering-pin regression block (== regression: mkdir runs before chown -R of the same tree (#550) ==), using the existing function-shadowing pattern (same technique as the #291 fw_then_compose block): shadow mkdir/sudo to emit mkdir-stats / chown-p2pool sentinels and assert the mkdir sentinel precedes the chown sentinel in both prepare_directories and reset_dashboard.

  • make lint: pass

  • tests/stack/run.sh on this branch: 1271 passed, 0 failed

  • Revert-proof: with the pithead reordering reverted (tests kept), both new assertions fail:

    ✗ prepare_directories: mkdir p2pool/stats precedes chown -R of P2POOL_DIR
        expected [mkdir-stats,chown-p2pool,], got [chown-p2pool,mkdir-stats,]
    ✗ reset-dashboard: mkdir p2pool/stats precedes chown -R of p2pool_dir
        expected [mkdir-stats,chown-p2pool,], got [chown-p2pool,mkdir-stats,]
    

🤖 Generated with Claude Code

…hboard

Both functions chown -R'd a data-dir tree to APP_UID and THEN ran an
unprivileged mkdir -p inside it — EACCES for any operator uid != 1000,
and in reset-dashboard the set -e abort landed after the data wipe,
stranding the install with no dashboard containers. Reorder to match
ensure_directories: every mkdir first, chown -R last. Pin the order
with a shadow-sudo/mkdir regression test in tests/stack/run.sh.

Closes #550

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@VijitSingh97
VijitSingh97 merged commit d95f83e into develop Jul 17, 2026
15 checks passed
@VijitSingh97
VijitSingh97 deleted the claude/fix-550-chown-order branch July 17, 2026 02:36
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.

setup/reset-dashboard: chown -R before unprivileged mkdir breaks operators with uid ≠ 1000

1 participant