Skip to content

[PATCH] Fix daemon crash on messages without From:/Sender: header - #13

Open
janmuennich wants to merge 1 commit into
croessner:masterfrom
dotplex:fix/no-from-header-keyerror
Open

[PATCH] Fix daemon crash on messages without From:/Sender: header#13
janmuennich wants to merge 1 commit into
croessner:masterfrom
dotplex:fix/no-from-header-keyerror

Conversation

@janmuennich

Copy link
Copy Markdown

eoh() falls back to hval="from" when no Sender: header is present, then unconditionally looks up self.__header[hval]. For messages carrying neither a From: nor a Sender: header (e.g. message-id=<>, common in spam and bounces), the "from" key is never populated by the header() callback, so the lookup raises KeyError inside the milter callback.

When that KeyError unwinds across the pymilter/libmilter thread boundary it can corrupt the exception object's refcount and abort the interpreter (CPython _PyObject_Dump of a KeyError instance), taking the whole daemon down. Postfix then waits out the milter timeout (300s) and falls back to milter_default_action, leaving From-domain verification disabled until the daemon is restarted.

Guard the lookup: when neither Sender: nor From: is present there is no domain to verify, so log and skip the message (Milter.CONTINUE), mirroring the existing empty-address skip path.

eoh() falls back to hval="from" when no Sender: header is present, then
unconditionally looks up self.__header[hval]. For messages carrying
neither a From: nor a Sender: header (e.g. message-id=<>, common in spam
and bounces), the "from" key is never populated by the header()
callback, so the lookup raises KeyError inside the milter callback.

When that KeyError unwinds across the pymilter/libmilter thread boundary
it can corrupt the exception object's refcount and abort the interpreter
(CPython _PyObject_Dump of a KeyError instance), taking the whole daemon
down. Postfix then waits out the milter timeout (300s) and falls back to
milter_default_action, leaving From-domain verification disabled until
the daemon is restarted.

Guard the lookup: when neither Sender: nor From: is present there is no
domain to verify, so log and skip the message (Milter.CONTINUE),
mirroring the existing empty-address skip path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant