Cyrus Sieve / libSieve buffer overflow

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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;
     }


[Index of Archives]     [Linux Security]     [Netfilter]     [PHP]     [Yosemite News]     [Linux Kernel]

  Powered by Linux