harden root writes into unprivileged-owned paths

Restrict the sweep sentinel to a mount at or below /media/frigate so a
parent /media mount cannot bless a later-shadowed volume. Rebuild
/tmp/nginx root-owned each start so root's cp and tempio writes cannot
follow a symlink an unprivileged nginx planted in the previous run.
This commit is contained in:
Josh Hawkins
2026-08-27 09:28:32 -05:00
parent 9f2cfb747c
commit 2ef2323fbd
2 changed files with 12 additions and 2 deletions
@@ -62,7 +62,13 @@ function set_worker_processes() {
sed -i "s/worker_processes auto;/worker_processes ${cpus};/" /tmp/nginx/conf/nginx.conf
}
# copied whole so the conf tree's relative includes still resolve
# Rebuilt root-owned and fresh every start. A previous unprivileged nginx owned
# this tree, and the cp and tempio writes below run as root: without wiping it
# first, a planted symlink here would let those writes land on any root file.
# rm does not traverse symlinks, and the bare mkdir fails closed if /tmp/nginx
# is raced into a symlink before we can create it.
rm -rf /tmp/nginx
mkdir /tmp/nginx
mkdir -p /tmp/nginx/conf /tmp/nginx/client_body /tmp/nginx/proxy \
/tmp/nginx/fastcgi /tmp/nginx/uwsgi /tmp/nginx/scgi
cp -r /usr/local/nginx/conf/. /tmp/nginx/conf/
@@ -156,8 +156,12 @@ if [[ "$(id -u)" -eq 0 ]]; then
# Only record the sentinel when something is mounted under /media: a
# sweep blessed against the container-local dir created below would let
# a volume attached later skip the sweep forever
# Only bless the sentinel when persistent storage actually backs
# /media/frigate, i.e. a mount at that exact path or below it. A mount
# at the /media parent does not count: a dedicated /media/frigate volume
# added later would shadow the swept directory and be skipped forever.
sentinel_args=(--sentinel /config/.permissions_version)
if ! awk '$2 == "/media" || $2 == "/media/frigate" || $2 ~ /^\/media\/frigate\//' /proc/mounts | grep -q .; then
if ! awk '$2 == "/media/frigate" || $2 ~ /^\/media\/frigate\//' /proc/mounts | grep -q .; then
sentinel_args=()
fi
/usr/local/bin/fix-ownership "${sentinel_args[@]}" \