app: the sender map's rebuild is serialised (audit W3)

Security audit 2026-10-17, finding W3 (low), stage 1. Resync read the
bindings and wrote the map with no lock (the selector table has tableMu);
two application changes at once could write in the order opposite to their
reads and leave the map stale - an application whose binding was missing
refused with reject_sender_login_mismatch until the next change. Now a
mutex on the Service holds the read, the write and the reload together.

Test: TestResyncRunsOneAtATime (eight at once, never two inside the
rebuild).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-17 21:55:07 +03:00
co-authored by Claude Opus 5.5
parent b81ff9f135
commit fd29468e00
4 changed files with 59 additions and 2 deletions
+3
View File
@@ -31,6 +31,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
- **A domain's DMARC reports are deleted with it** (audit A5/W2): reports
belong to a domain by name, and a domain deleted and added again showed
its old reports to whoever it was assigned to then.
- **The sender map is rebuilt one change at a time** (audit W3): two
application changes at once could leave the map without the newer one
until the next change.
- **A stranger's recipient no longer writes an Inbound › Log row** (audit
M2): Postfix quotes a refused recipient in its reply with the quotes
removed, so `RCPT TO:<"; from=<x> to=<y> …"@domain>` spelled a second