harness: drop trailing /bin from systemd path entries so wrapper sudo resolves (#672 fixup)

systemd.services.<name>.path appends /bin to each entry, so the
literal '/run/wrappers/bin' here was being expanded to
'/run/wrappers/bin/bin' inside the unit's PATH — a path that
doesn't exist. 'which sudo' then fell back to
'/run/current-system/sw/bin/sudo' (the non-setuid nix-store binary)
and refused with 'must be owned by uid 0 and have the setuid bit
set' on every agent, despite hyperhive.user.passwordlessSudo = true.

Verified on this container post-rebuild:
  PATH includes /run/wrappers/bin/bin (non-existent)
  /run/wrappers/bin/sudo exists with mode r-s--x--x (real setuid)
  but `sudo` resolves to /run/current-system/sw/bin/sudo and fails.

Fix: drop the trailing /bin from both entries. systemd appends it.

The /run/current-system/sw entry was already correctly
expanding to /run/current-system/sw/bin (because of the same
auto-append), which is why everything else on PATH worked despite
the broken wrappers entry — only sudo (the one binary that needs
the wrapper dir) was affected.
This commit is contained in:
iris 2026-05-31 11:24:23 +02:00 committed by Mara
commit b714ba15c2

View file

@ -1269,8 +1269,17 @@ in
# `hyperhive.user.passwordlessSudo = true` is configured
# (#672 fixup pulled forward into this PR to avoid the
# regression argus flagged on #676).
#
# `systemd.services.<name>.path` appends `/bin` to each entry,
# so the bare prefixes here resolve to `/run/wrappers/bin` +
# `/run/current-system/sw/bin` inside the unit's PATH. Passing
# the trailing `/bin` ourselves (the natural-looking spelling)
# would yield `/run/wrappers/bin/bin` + `/run/current-system/sw/bin/bin`,
# neither of which exists — that's how #672 originally landed
# broken: every agent had a PATH pointing at non-existent dirs
# and `which sudo` kept falling back to the un-setuid binary.
path = [
"/run/wrappers/bin"
"/run/wrappers"
"/run/current-system/sw"
];
environment = {