-
Notifications
You must be signed in to change notification settings - Fork 43
Open
Description
Brief Description:
- Nullmailer-smtpd reproducibly exits unexpectedly with value 141 if it attempts to write DATA content to a failed stream.
- This bug is ONLY apparent after the segfault bug (issue reproducible crash when calling nullmailer-smtpd from swaks #95) is patched.
Steps to reproduce (see issue #95):
- Give nullmailer-smtpd a malformed payload, where either the MAIL FROM or the RCPT TO target is invalid
- For example:
HELO a\n
MAIL FROM:<b>\n
RCPT TO:<c>\n
DATA\n
line 1\r\n
\r\n.\r\n
Expected behavior: any of the following.
- nullmailer-smtpd should report an SMTP error message.
- reject invalid MAIL FROM or RCPT TO
- report to ferr that write to stream has failed
Resulting behavior:
/app# nullmailer-smtpd
220 nullmailer-smtpd ready
HELO a
250 2.3.0 OK
MAIL FROM:<b>
250 2.1.0 Sender accepted
RCPT TO:<[email protected]>
250 2.1.5 Recipient accepted
DATA
354 End your message with a period on a line by itself
line 1
/app# echo $?
141
(141 = 128 + SIGPIPE)
Root cause:
Running in gdb shows that src/smtpd.cc, qwrite attempts to write to a closed file descriptor (line 118). Verified with signal handling patch (see fix below).
Impact:
- SMTP clients are able to cause failure of nullmailer-smtpd.
- nullmailer-smtpd exits without providing useful information why.
Fix(es):
Implementing a signal handler to catch SIGPIPE in src/smtpd.cc avoids a program crash. Here is a hacky proof of concept:
@@ -111,9 +111,16 @@
return fout;
}
+static void pipe_handler(const int signal_num)
+{
+ ferr << "signal " << signal_num << ".\n";
+ respond(resp_qwrite_err);
+}
+
static bool qwrite(int qfd, const char* data, size_t len)
{
ssize_t wr;
+ signal(SIGPIPE, pipe_handler);
while (len > 0) {
wr = write(qfd, data, len);
if (wr <= 0)
Resulting behavior, avoiding a crash:
/app# nullmailer-smtpd
220 nullmailer-smtpd ready
HELO me
250 2.3.0 OK
MAIL FROM:<a>
250 2.1.0 Sender accepted
RCPT TO:<[email protected]>
250 2.1.5 Recipient accepted
DATA
354 End your message with a period on a line by itself
line 1
451 4.3.0 Write to nullmailer-queue failed
451 4.3.0 Write to nullmailer-queue failed
signal 13.
nullmailer-smtpd: nullmailer-queue failed: 1
QUIT
221 2.0.0 Good bye
``
Metadata
Metadata
Assignees
Labels
No labels