fix(packaging): accept watchdog pings from the daemon only (B245)

This commit is contained in:
nvrl committed 2026-10-16 12:17:53 +02:00
1 parent aa0c60f5a2
commit 4bf176a631
2 files changed
+32 -3

No files matched your search

+22
View File
@@ -100,6 +100,7 @@ a live account since.
| Entry | Title | | Entry | Title |
|---|---| |---|---|
| [B245](#b245--any-child-of-the-daemon-can-answer-the-watchdog-for-it) | Any child of the daemon can answer the watchdog for it |
| [B244](#b244--photos-without-a-sidecar-or-a-dated-name-are-filed-under-the-upload-day) | Photos without a sidecar or a dated name are filed under the upload day | | [B244](#b244--photos-without-a-sidecar-or-a-dated-name-are-filed-under-the-upload-day) | Photos without a sidecar or a dated name are filed under the upload day |
| [B243](#b243--a-hung-mount-freezes-the-app-when-a-file-is-opened) | A hung mount freezes the app when a file is opened | | [B243](#b243--a-hung-mount-freezes-the-app-when-a-file-is-opened) | A hung mount freezes the app when a file is opened |
| [B242](#b242--opening-a-large-photo-freezes-the-app) | Opening a large photo freezes the app | | [B242](#b242--opening-a-large-photo-freezes-the-app) | Opening a large photo freezes the app |
@@ -347,6 +348,27 @@ a live account since.
Newest first. Newest first.
### B245 — Any child of the daemon can answer the watchdog for it
**Status:** Fixed, not verified live
**Found:** 2026-10-16, architecture audit (`FINDINGS.md` section 3, systemd unit).
**Where:** `packaging/proton-drive.service`
**Repro:** A child of the daemon, such as `ffmpeg` making a video thumbnail, inherits
`NOTIFY_SOCKET` and can send `WATCHDOG=1` while the daemon itself is wedged.
**Cause.** The unit set `NotifyAccess=all`, which accepts notifications from every process of the
unit. The watchdog exists to restart a daemon that stopped answering, and any child could keep it
from doing that.
**Fix.** `NotifyAccess=main`: only the daemon's own process is heard. The rest of the hardening
the audit listed was left out on purpose. In a user unit every seccomp-based option implies
`NoNewPrivileges`, which stops the setuid `fusermount3` from mounting.
**Test:** none automated; `systemd-analyze verify --user` accepts the unit.
---
### B244 — Photos without a sidecar or a dated name are filed under the upload day ### B244 — Photos without a sidecar or a dated name are filed under the upload day
**Status:** Fixed, not verified live **Status:** Fixed, not verified live
+10 -3
View File
@@ -8,10 +8,17 @@ PartOf=graphical-session.target
[Service] [Service]
# Deliberately not Type=notify: the daemon waits for a stored login before it # Deliberately not Type=notify: the daemon waits for a stored login before it
# mounts anything, and a machine that boots before the user logs in would then # mounts anything, and a machine that boots before the user logs in would then
# fail the unit on the start timeout. NotifyAccess=all gets the daemon a # fail the unit on the start timeout. NotifyAccess=main gets the daemon a
# NOTIFY_SOCKET all the same, which is all the watchdog below needs. # NOTIFY_SOCKET all the same, which is all the watchdog below needs, and keeps
# its children (fusermount3, ffmpeg, exiftool) from answering the watchdog for
# it. "all" let any of them do so.
#
# Most sandboxing options are left out on purpose: in a user unit, every
# seccomp-based one (SystemCallFilter, LockPersonality, RestrictAddressFamilies
# and the like) implies NoNewPrivileges, which stops the setuid fusermount3
# from mounting anything.
Type=simple Type=simple
NotifyAccess=all NotifyAccess=main
# The daemon waits for a stored login, mounts ~/ProtonDrive, and keeps it # The daemon waits for a stored login, mounts ~/ProtonDrive, and keeps it
# mounted. SIGTERM (from `systemctl --user stop`) triggers a clean lazy unmount. # mounted. SIGTERM (from `systemctl --user stop`) triggers a clean lazy unmount.
ExecStart=/usr/bin/pdfs daemon ExecStart=/usr/bin/pdfs daemon