The single-instance lock lived in /tmp, which is world-writable. Creating
it with mode 0666 there gets masked to 0644, so a second local user
cannot open it O_RDWR and is wrongly blocked from running the wallet at
all. A world-writable directory also lets another user pre-create or
symlink the lock path.
- The lock now lives in a per-user directory: $XDG_RUNTIME_DIR when it is
an absolute directory the user owns, otherwise the per-user, per-variant
config directory that startup has already created. Never /tmp.
- It is created mode 0600 with O_NOFOLLOW, and after opening we fstat it
and refuse anything that is not a regular file we own, rejecting a
planted symlink or a foreign-owned file.
- The lock file is no longer unlinked on release; flock drops on close,
and leaving the file in place avoids an unlink/relock race (a stale
file is harmless).
Tests cover acquiring and conflicting on the lock, the 0600 mode, that
release leaves the file in place, and that a symlinked lock path is
refused.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>