Entrypoint changes a mode through a symbolic link in the data directory #77

Closed
opened 2026-09-29 12:05:41 +02:00 by clawbot · 1 comment
Collaborator

Found in the review of #76 (#76 (comment)); PR 76 was merged before the fix, so it is on next and main.

bin/entrypoint.sh runs as root and does chmod 750 /data "$DATA_DIR". chmod follows a symbolic link. DATA_DIR is /data/reports by default, inside /data, which the netwatch user owns after the first start. So if /data/reports is a symbolic link to a directory, the next start sets mode 750 on that directory wherever it is in the container: a link to /etc leaves /etc at 750, and a link to /usr/share/nginx/html stops nginx serving the page while the health check still passes.

Definition of done

  • The entrypoint never changes an owner or a mode through a symbolic link: when DATA_DIR or /data is a symbolic link, the start stops with an error naming the variable, before any chown or chmod.
  • Verified by running the image with a bind mount: with /data/reports linked to /etc, the start stops naming DATA_DIR and /etc keeps its mode; an empty root-owned directory and one holding another uid's files still turn healthy with the backend running as netwatch.
  • Root make check and script/cibuild pass; TODO.md updated in the same commit; commit title ends (closes #N).

Model: opus-5-5

Found in the review of https://git.eeqj.de/sneak/netwatch/pulls/76 (https://git.eeqj.de/sneak/netwatch/pulls/76#issuecomment-106880); PR 76 was merged before the fix, so it is on `next` and `main`. `bin/entrypoint.sh` runs as root and does `chmod 750 /data "$DATA_DIR"`. `chmod` follows a symbolic link. `DATA_DIR` is `/data/reports` by default, inside `/data`, which the `netwatch` user owns after the first start. So if `/data/reports` is a symbolic link to a directory, the next start sets mode 750 on that directory wherever it is in the container: a link to `/etc` leaves `/etc` at 750, and a link to `/usr/share/nginx/html` stops nginx serving the page while the health check still passes. ## Definition of done - The entrypoint never changes an owner or a mode through a symbolic link: when `DATA_DIR` or `/data` is a symbolic link, the start stops with an error naming the variable, before any `chown` or `chmod`. - Verified by running the image with a bind mount: with `/data/reports` linked to `/etc`, the start stops naming `DATA_DIR` and `/etc` keeps its mode; an empty root-owned directory and one holding another uid's files still turn healthy with the backend running as `netwatch`. - Root `make check` and `script/cibuild` pass; `TODO.md` updated in the same commit; commit title ends ` (closes #N)`. Model: opus-5-5
clawbot self-assigned this 2026-09-29 12:05:41 +02:00
Author
Collaborator

Already fixed on next and main: the rework commit became the head of #76 before sneak merged it (a5ca73c). bin/entrypoint.sh stops, naming DATA_DIR, when readlink -f does not return /data and DATA_DIR unchanged, before any chown or chmod; the release review of main on #74 checks it.

Disclosure: mkdir -p "$DATA_DIR" runs before the check, so with a DATA_DIR two or more levels below /data a planted link can make root create an empty directory where it points; no owner or mode is changed.

Model: opus-5-5

Already fixed on `next` and `main`: the rework commit became the head of https://git.eeqj.de/sneak/netwatch/pulls/76 before sneak merged it (`a5ca73c`). `bin/entrypoint.sh` stops, naming `DATA_DIR`, when `readlink -f` does not return `/data` and `DATA_DIR` unchanged, before any `chown` or `chmod`; the release review of `main` on https://git.eeqj.de/sneak/netwatch/pulls/74 checks it. Disclosure: `mkdir -p "$DATA_DIR"` runs before the check, so with a `DATA_DIR` two or more levels below `/data` a planted link can make root create an empty directory where it points; no owner or mode is changed. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#77