Wednesday 16 February 2011

I never heard of Agnitas EMM until today

One of our servers has been blowing up occasionally. After a few failed attempts, I managed to use gdb to write out the file our process was trying to parse:


(gdb) call open("/tmp/x", 0101, 0777);
$17 = 3
(gdb) call write(3, body_data._M_dataplus._M_p, strlen(body_data._M_dataplus._M_p))
[wait... then hit ^C]
$18 = 1782948729

So clearly there's a missing NUL termination. Hardly surprising for this kind of bug. I just used dd to reduce the file to what seemed like the relevant data, exluding random junk from the process' memory.

And... bingo!

X-Mailer: Agnitas EMM 7.0
...
X-Barracuda-BRTS-Evidence: 5367d33c72fcbdfe74e38a30b0711cd7-9667-unk
X-Barracuda-BRTS-Evidence: c57ea21d3b9fd34cfd1e59d35e55f1c9-4515-unk
X-OriginalArrivalTime: 16 Feb 2011 13:34:07.0165 (UTC) FILETIME=[2F631ED0:01CBCDDE]
X-Recipient-Count: 1
X-Incoming-Message-Id: 1PphWB-0003Zl-Bu
X-Sender-Host-Name: mail.example.com
X-Sender-Host-Address: 192.168.17.42
X-Sender-Auth:

This is a multi-part message in MIME format.

---==AGNITASOUTER164240059B290156CA==
Content-Type: multipart/alternative;

boundary="-==AGNITASINNERB164240059B290156CA=="

The last five of those X- headers are ones we add. But look at that blank line between the MIME part's Content-Type: header and the boundary=... parameter. Just look at it! That blank line caused our process to not know what message part boundary to look for, so it just went into infinite loop apoplexy, gobbling up memory until the OOM killer zapped it.

Oh wow, they offer some presumably older version of EMM for download from sourceforge. Let's take a quick dive into their source code:


else if (n == 1) // online HTML
buf.append ("HContent-Type: multipart/alternative;" + data.eol +
"\tboundary=\"" + xmlStr (outerBoundary) + "\"" + data.eol);
...
if (n == 2)
buf.append ("Content-Type: multipart/alternative;" + data.eol +
" boundary=\"" + xmlStr (innerBoundary) + "\"" + data.eol +
data.eol +
"--" + xmlStr (innerBoundary) + data.eol);
...
else if (n == 1)
buf.append ("Content-Type: multipart/alternative;" + data.eol +
"\tboundary=\"" + xmlStr (outerBoundary) + "\"" + data.eol +
data.eol);
...
if (n == 2)
buf.append ("Content-Type: multipart/alternative;" + data.eol +
" boundary=\"" + xmlStr (innerBoundary) + "\"" + data.eol +
data.eol +
"--" + xmlStr (innerBoundary) + data.eol);

Nope, doesn't look like EMM is likely to be adding the extra newline. So I don't know who is. Maybe Barracuda Network are doing something nasty? I can't tell, because there's nothing relevant I can (easily) find on their website.

No comments:

Post a Comment