fix(init): refuse to copy the install tree onto itself
copyFilesFromLocal ran `rm -rf "$script_dir"` before ever reading the source. When source and destination resolve to the same path — which is what happens if you run `sudo ./init.sh init` from inside /libreportal-system/install, an easy mistake when re-running to re-bake the footprint — the rm deletes the source too, the copy then fails, and the script exits. The damage is worse than a failed copy: it exits before initRootHelpers and before the sudoers tightening, so the install tree is gone AND the manager is left holding the install-phase grant (ALL=(ALL) NOPASSWD: ALL) instead of the scoped allowlist. I did exactly this on a live box; the tree was recoverable from git, but the loose sudo rule is the part that matters. Now: resolve both paths and refuse if they match, and validate the source before destroying the destination rather than after. Both checks run ahead of the rm. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
bd10a9ab55
commit
6861358809
27
init.sh
27
init.sh
@ -453,7 +453,32 @@ copyFilesFromLocal() {
|
||||
fi
|
||||
|
||||
isHeader "Copying from Local Directory"
|
||||
|
||||
|
||||
# Refuse to copy a directory onto itself. Everything below deletes the
|
||||
# destination BEFORE reading the source, so when the two resolve to the same
|
||||
# path the rm wipes the source too and the copy fails with the tree already
|
||||
# gone — taking the install down and stopping short of the root-helper bake
|
||||
# and the sudoers tightening, leaving install-phase sudo in place.
|
||||
# Running `sudo ./init.sh init` from inside the install tree is enough to hit
|
||||
# it, which is an easy mistake when re-running to re-bake the footprint.
|
||||
local _src_real _dst_real
|
||||
_src_real="$(readlink -f "$source_dir" 2>/dev/null || echo "$source_dir")"
|
||||
_dst_real="$(readlink -f "$script_dir" 2>/dev/null || echo "$script_dir")"
|
||||
if [[ "$_src_real" == "$_dst_real" ]]; then
|
||||
isError "Source and destination are the same directory ($_dst_real)."
|
||||
isNotice "Run init.sh from your source checkout, not from inside the install tree."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate the source BEFORE destroying the destination, for the same reason:
|
||||
# a bad source used to be discovered only after the install tree was gone.
|
||||
# detectLocalLibrePortal derives the directory the same way source_dir is
|
||||
# derived above, so it checks exactly what is about to be copied.
|
||||
if ! detectLocalLibrePortal >/dev/null 2>&1; then
|
||||
isError "$source_dir is not a valid LibrePortal source — refusing to replace $script_dir."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove existing install directory
|
||||
sudo rm -rf "$script_dir"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user