Cyrus Sieve / libSieve buffer overflow

From: Timo Sirainen (tssat_private)
Date: Mon Dec 02 2002 - 09:56:45 PST

  • Next message: Michael S. Scheidell: "[VU#317417] Denial of Service condition in vxworks ftpd/3com nbx"

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



    This archive was generated by hypermail 2b30 : Mon Dec 02 2002 - 16:14:22 PST