fix(entrypoint): unlink planted symlinks as the customer, then fail closed

Root rm -f in drop_symlink could be redirected by a parent-directory swap to
delete arbitrary files as root. drop_symlink and the logs/ symlink sweep now
unlink AS THE CUSTOMER (can never delete anything the customer couldn't), and
drop_symlink still refuses to start if the path is a symlink afterwards; the
pre-daemon logs/ gate re-checks and fails closed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shadowdaoandClaude Opus 5.5 committed 2026-10-20 16:06:41 -07:00
1 parent d400d5eb39
commit 4064d9d6aa
1 file changed
+10 -6
+10 -6
View File
@@ -37,12 +37,14 @@ die() {
echo "entrypoint: FATAL: $* - refusing to start" >&2
exit 1
}
# Unlink as root: rm on the final component never touches the link target and
# the customer cannot deny it. Still a symlink afterwards -> refuse to start.
# Unlink AS THE CUSTOMER: rm on the final component never touches the link
# target, and if a parent dir is swapped for a symlink mid-way the customer can
# only delete what they already could. Still a symlink afterwards -> refuse to
# start (fail closed).
drop_symlink() {
if [ -L "$1" ]; then
echo "entrypoint: SECURITY: $1 was a symlink to '$(readlink "$1")' - removing" >&2
rm -f -- "$1"
as_user rm -f -- "$1"
[ -L "$1" ] && die "could not remove symlink $1"
fi
return 0
@@ -55,9 +57,11 @@ chown -h $user:$user /home/$user
# alone, and every root-side operation on it below runs as the customer.
drop_symlink /home/$user/logs
if [ -d /home/$user/logs ]; then
# nginx opens its logs here as root. find without -L never follows symlinks;
# -delete unlinks the link itself. Re-checked fail-closed before nginx starts.
find /home/$user/logs -xdev -type l \
# nginx opens its logs here as root. As the customer: find without -L never
# follows symlinks, -delete unlinks the link itself, and a raced parent swap
# can only reach what the customer could already delete. Re-checked
# fail-closed immediately before nginx starts.
as_user find /home/$user/logs -xdev -type l \
-printf 'entrypoint: SECURITY: %p was a symlink to %l - removed\n' -delete >&2 || true
fi