On Thu, 14 Aug 2003, I wrote:
> > Could you please clarify under which circumstances the bug might
> > be triggered?
>
> I was giving people who feel really paranoid a chance to get the patch
> on before saying anything more - and also giving the geeks a chance to
> read the patch and try to figure it out as an exercise... the poster of
> the first correct explanation wins a free copy of Exim 4.22. :-)
The final part of that posting was meant as a joke, but some people
thought I was trying to turn a security problem into a puzzle, and took
issue with me. That wasn't the idea; the first clause was the serious
point. My apologies to those who were offended.
Anyway, the patches have now been out for 24 hours, so I will post
details of the problem:
1. Exim reads incoming SMTP commands into a buffer which is 512 bytes
long. This number comes from RFCs 821 and 2821. The buffer is in heap
memory, obtained from malloc(). Commands that are too long are rejected
as "unknown command".
2. When an SMTP command is read, any trailing whitespace is removed
and a trailing NUL is added to turn the command into a C string before
it is processed.
3. When an EHLO or HELO command is received without any arguments, Exim
includes the text "(no argument given)" in the syntax error message that
this causes.
4. Formerly, Exim was placing that string in the command buffer. It put
it at the point where the EHLO/HELO argument should have been. Because
of (2), it assumed that this would be at offset 5 in the buffer, and
therefore there would be no space problem.
5. However, if Exim received EHLO/HELO followed by around 500 spaces,
followed by a NUL character and CRLF, the spaces were not removed as
trailing spaces, and were skipped over when searching for an argument,
leaving the "this is where the argument should have been" pointer near
the end of the buffer.
6. Then the "(no argument given)" string could be inserted so near the
end of the buffer that it overflowed.
7. Exim would be running as "exim:exim" at the time, not as root. It is
not known if this bug could actually be exploited.
Two fixes have been applied in Exim 4.21:
(a) The rather silly code for generating the error message has been
re-written so as not to put "(no argument given)" in the command buffer.
(I have no idea why it was the way it was. Probably a hangover from
something that got changed, but it is so old - same in Exim 3 - that I
cannot remember.)
(b) Exim now complains if it receives a NUL character in an SMTP
command. This is certainly forbidden by the RFCs.
The patches issued for 4.20 and 3.36 contain (a) only.
Hindsight:
If I were to write Exim all over again, I would probably avoid using C
strings entirely. (These days one should probably use entirely UTF-8
strings, but that wasn't as obvious 8 years ago.)
Philip
--
Philip Hazel University of Cambridge Computing Service,
ph10@??? Cambridge, England. Phone: +44 1223 334714.