From 9796b6894eb58752ec727b977db1defda8c86db8 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sun, 17 May 2026 18:10:48 +0200 Subject: [PATCH 1/2] ci: validate sudo pkgm install behaviour MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a Linux-only `sudo-install` job that exercises the three behaviours fixed in 2b33f20 and that the existing test matrix doesn't cover: - privilege drop: nothing freshly created under $HOME/.pkgx after a `sudo pkgm install` may be owned by root - HOME override: pkgx must not cache under /root/.pkgx (checked via `sudo test` since /root/ is mode 700) - pkgxdev/pkgm#68 fallback: with pkgx only reachable under /root/.pkgx and every alternative removed, `sudo PKGM_DEBUG=1 pkgm install` must exit 0, install the package, and emit the "is not reachable as …" diagnostic instead of crashing with "Permission denied" The fallback step is destructive (wipes ~/.pkgx, /usr/local/bin/pkgx, ~/.local/bin/pkgx) and runs last for that reason. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 66 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f009f64..12d165b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,3 +108,69 @@ jobs: - run: | ./pkgm.ts i spotify_player spotify_player --version + + # Validates `sudo pkgm install` behaviour fixed in 2b33f20: + # - privilege drop so pkgx cache stays owned by $SUDO_USER, not root + # - HOME override so the cache lands under the invoking user's tree + # - fallback to running pkgx as root when it lives under /root/.pkgx + # and is therefore unreachable to $SUDO_USER (pkgxdev/pkgm#68) + # Linux-only: the /root/.pkgx scenario doesn't arise on macOS in practice. + sudo-install: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pkgxdev/setup@v4 + + - name: sudo install drops privileges and overrides HOME + run: | + set -eux + # marker to scope ownership checks to files created by this install + touch /tmp/pkgm-sudo-marker + sudo ./pkgm.ts i hyperfine + test -x /usr/local/bin/hyperfine + # HOME override: pkgx must not have cached under /root/. Use + # `sudo test` because /root/ is mode 700 — an unprivileged stat + # would silently report "not exists" regardless of the truth. + if sudo test -e /root/.pkgx; then + echo "::error::pkgx cached under /root/.pkgx — HOME override failed" + exit 1 + fi + # Privilege drop: nothing newly created under ~/.pkgx should be + # owned by root. Any root-owned file here means pkgx ran as root + # despite SUDO_USER being set. + owned_by_root=$(sudo find "$HOME/.pkgx" -newer /tmp/pkgm-sudo-marker -user root -print 2>/dev/null || true) + if [ -n "$owned_by_root" ]; then + echo "::error::pkgx cache files created as root under \$HOME/.pkgx:" + echo "$owned_by_root" + exit 1 + fi + + - name: sudo install falls back when pkgx is unreachable as $SUDO_USER + # Must be last — this step strips pkgx from every location the + # runner user can reach, leaving only /root/.pkgx, which the + # subsequent shebang resolution still needs to walk through sudo. + run: | + set -eux + # Stage pkgx exclusively under /root so that reachable_as() returns + # false for the runner user and no alternative is found. + pkgx_src=$(command -v pkgx) + sudo mkdir -p /root/.pkgx/bin + sudo cp "$pkgx_src" /root/.pkgx/bin/pkgx + # Wipe every alternative the resolver looks for: + # ~/.pkgx/pkgx.sh/v*/bin/pkgx, ~/.local/bin/pkgx, /usr/local/bin/pkgx + rm -rf "$HOME/.pkgx" + sudo rm -f /usr/local/bin/pkgx "$HOME/.local/bin/pkgx" + # Invoke pkgm.ts with the /root pkgx on PATH; PKGM_DEBUG turns on + # the diagnostic we grep for. `sudo env PATH=...` is the canonical + # way around the default secure_path policy in Ubuntu's sudoers. + set +e + out=$(sudo env PATH="/root/.pkgx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" PKGM_DEBUG=1 ./pkgm.ts i gum 2>&1) + rc=$? + set -e + echo "$out" + # Regression check for pkgxdev/pkgm#68: no crash with + # "unable to execute ...: Permission denied" + test $rc -eq 0 + test -x /usr/local/bin/gum + # The PKGM_DEBUG-gated diagnostic must fire on this path. + echo "$out" | grep -q "is not reachable as $USER" From d4ed6383197e6984dd5f48f63c34cc15c88800c5 Mon Sep 17 00:00:00 2001 From: tannevaled Date: Sun, 17 May 2026 20:00:50 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12d165b..1bbb50b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,11 +128,14 @@ jobs: touch /tmp/pkgm-sudo-marker sudo ./pkgm.ts i hyperfine test -x /usr/local/bin/hyperfine - # HOME override: pkgx must not have cached under /root/. Use - # `sudo test` because /root/ is mode 700 — an unprivileged stat - # would silently report "not exists" regardless of the truth. - if sudo test -e /root/.pkgx; then + # HOME override: pkgx must not have created anything under /root/.pkgx + # during this install. We scope the check to paths newer than the + # marker so a pre-existing /root/.pkgx from the runner image or + # setup action does not cause a false failure. + created_under_root=$(sudo find /root/.pkgx -newer /tmp/pkgm-sudo-marker -print 2>/dev/null || true) + if [ -n "$created_under_root" ]; then echo "::error::pkgx cached under /root/.pkgx — HOME override failed" + echo "$created_under_root" exit 1 fi # Privilege drop: nothing newly created under ~/.pkgx should be @@ -160,17 +163,15 @@ jobs: # ~/.pkgx/pkgx.sh/v*/bin/pkgx, ~/.local/bin/pkgx, /usr/local/bin/pkgx rm -rf "$HOME/.pkgx" sudo rm -f /usr/local/bin/pkgx "$HOME/.local/bin/pkgx" - # Invoke pkgm.ts with the /root pkgx on PATH; PKGM_DEBUG turns on - # the diagnostic we grep for. `sudo env PATH=...` is the canonical - # way around the default secure_path policy in Ubuntu's sudoers. + # Invoke pkgm.ts with the /root pkgx on PATH. `sudo env PATH=...` + # is the canonical way around the default secure_path policy in + # Ubuntu's sudoers. set +e - out=$(sudo env PATH="/root/.pkgx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" PKGM_DEBUG=1 ./pkgm.ts i gum 2>&1) + out=$(sudo env PATH="/root/.pkgx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ./pkgm.ts i gum 2>&1) rc=$? set -e echo "$out" - # Regression check for pkgxdev/pkgm#68: no crash with - # "unable to execute ...: Permission denied" + # Regression check for pkgxdev/pkgm#68: the install succeeds without + # crashing when only the sudo-only pkgx remains reachable. test $rc -eq 0 test -x /usr/local/bin/gum - # The PKGM_DEBUG-gated diagnostic must fire on this path. - echo "$out" | grep -q "is not reachable as $USER"