[Raw Msg Headers][Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fix for a bug in makeHeader...

We've been using ZMailer for about a year now as the MTA on our central
'router' machine. Periodically, we see ZM-router processes dying and
dumping core. The files which cause these deaths all appear to have one
thing in common: headers without keywords, to wit:
        From: foo@bar.baz.edu
        To: qux@quux.quuux.com
        : This is a null header

rfc822.c actually has code to guard against this, and insert an
'X-Null-Field' keyword to qualify such blatant silliness; unfortunately,
makeHeader (in rfc822hdrs.c) chokes when trying to deal with it, causing
SIGSEGV and core dump.

The specific problem is this: makeHeader's last two parameters are a line
from the header and the length of the 'keyword' (e.g. 'From') part of it.
makeHeader uses 'len' to find the end of the substring containing the
keyword, saves the contents of (s+len) (usually a colon), replaces it with
a null and passes the resulting, truncated s to find_header. When
find_header returns, the colon is restored.

Which is all well and good except that, since, in the case of
'X-Null-Field', (s+len) walks right off the end, since makeLetter only
passes that, not that plus the bad header line.

The answer I've chosen is to just not bother with all the rigmarole if len
and strlen(s) are identical -- there will be nothing to save and no reason
to truncate the string.

Here is the altered segment of makeHeader. Is there anything obviously wrong
with this? My tests seem to work...

/* MSS1 says if len == strlen(s) (like, if its the null-header
   case) we don't need to try to add a null -- in fact, it will
   break rather nastily and crash the router with a SIGSEGV */

        if (len != strlen(s)) {
                c = *(s+len);
                *(s+len) = '\0';
                hlp = find_header(db, s);
                *(s+len) = c;
        } else {
                hlp = find_header(db, s);

Michael Scott Shappe
CIT Collaboration Systems
PEM/RIPEM public key available upon request.