mirror of
https://github.com/mailscope/kumomta.git
synced 2026-08-24 21:28:18 +00:00
3788f838d3
We spent some time running down an issue where the combination of the root-user umask and some ad-hoc testing to recreate the spool directory led to a very difficult to understand situation where the spool seemed to corrupt itself on the next restart. The root cause was that the spool directories had been re-created by the operator with permissions that led to an asymmetric filesystem view for the dropped privs scenario (eg: the default when running via systemd). The crux of it is that the explicit existence check used by rocksdb to determine if the database was new or pre-existing was inconsistent with what the kernel actually allowed for the permissions on the directory, causing the second start to believe that it was a new database, then surprise itself when it found other evidence that it wasn't new at all. This commit adds a dir-probe crate that tests for this misconfiguration and raises an error before rocksdb can try to open and corrupt itself. We can't reasonably exercise this in CI because of the priv dropping component, but the included example probe utility confirmed it for me outside of the harness: ``` bdad88ed680e# install -d -o wez -g wez -m 2700 /tmp/probe-demo bdad88ed680e# ./target/debug/examples/probe /tmp/probe-demo --user wez probing /tmp/probe-demo as ruid=0 euid=1000 rgid=1000 egid=1000 FAIL: /tmp/probe-demo (directory owner uid=1000 gid=1000 mode=2700); process ruid=0 euid=1000 rgid=1000 egid=1000: inconsistent view of /tmp/probe-demo/.kumo-dir-probe9nMaUj.renamed: access(2) reports the file present=false but open(2) reports it present =true. This means the process real and effective user ids differ (a privilege drop) and the directory permissions are too restr ictive for one of those identities. A database opened here would decide to create a fresh instance yet write over the existing files, corrupting itself on the next startup. Ensure the directory is owned by, and grants rwx to, the identity the service run s as. bdad88ed680e# chmod 2755 /tmp/probe-demo bdad88ed680e# ./target/debug/examples/probe /tmp/probe-demo --user wez probing /tmp/probe-demo as ruid=0 euid=1000 rgid=1000 egid=1000 PASS: /tmp/probe-demo is usable by this identity bdad88ed680e# rm -rf /tmp/probe-demo ```