fix(entrypoint): no recursive chmod on the customer home; root never follows customer symlinks #3
+10
-6
@@ -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
|
||||
|
||||
|
||||
Reference in new issue
Block a user