18 Aug 22:32
Re: [Fwd: mutt buffer overflow]
Thomas Roessler <roessler <at> does-not-exist.org>
2005-08-18 20:32:27 GMT
2005-08-18 20:32:27 GMT
On 2005-08-18 19:25:54 +0100, Lars Hecking forwarded from bugtraq: > overwriting other memory with many possible consequences. This > counter should never exceed the size and I believe the logic in > the convert_to_state() function is supposed to reset it to 0, > however there is a flaw - I have included a possible fix but I'm > not sure it's the 100% correct fix and there seem to be no > developers willing to fix this so far. There are other functions > affected in the same way due to copy/paste, such as > mutt_decode_uuencoded() that this patch should also fix. To begin with, neither of the proof of concept examples [1], [2] posted to bugtraq leads to a buffer overflow here (latest CVS built on Fedora Core 4). 1. ftp://ftp.00f.net/misc/mutt-crash-poc.mbox 2. http://sightly.net/peter/tmp/mutt-bug So Frank's observation that this might be tied to a particular iconv implementation seems to be valid. Still, the question is if mutt is making assumptions that it shouldn't make, or if that iconv implementation is broken. The assumption that is made in mutt_decode_xbit is that mutt_convert_to_state actually decreases the l counter by at least one -- if l is sufficiently large. This maps to a similar assumption that mutt_iconv doesn't return without at least consuming one byte. mutt_convert_to_state invokes mutt_iconv with inrepls set to 0, and outrepl being "?", which immediately leaves out a lot of the complexity in that function. Reading through it, the one way in which that function does not consume any input is when the input buffer begins with an incomplete multibyte sequence. Our assumption now becomes that any string of sufficient length either begins with a valid (hence consumed, at least partially) or invalid (hence skipped) multibyte sequence, but not with an incomplete one. I'd be curious to hear what the attached program prints on a platform where the iso-2022-jp example [1] leads to a crash. Regards, -- Thomas Roessler ยท Personal soap box at <http://log.does-not-exist.org/>.
#include <stdio.h>
#include <string.h>
#include <iconv.h>
#include <errno.h>
int main ()
{
iconv_t cd = iconv_open ("ISO_8859-15", "ISO-2022-JP");
char _ib[] = "\033AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
char _ob[1000];
size_t ibl = sizeof (_ib) - 1;
size_t obl = sizeof (_ob);
char *ib = _ib;
char *ob = _ob;
int rv = iconv (cd, &ib, &ibl, &ob, &obl);
printf ("rv = %d, errno = %d (%s)\n",
rv, errno, errno == EILSEQ ? "EILSEQ" : errno == EINVAL ? "EINVAL" : "?");
printf ("'%s'\n", _ob);
return 0;
}
RSS Feed