Subject: Cyrus SASL library buffer overflows These overflows are found at least in version 2.1.9, none of them are present in 1.5.28. 2.1.10 was just released which fixed the problems. Note that besides the Cyrus project itself, the SASL library is also used by Postfix-TLS patch, OpenLDAP and probably some other servers. Problem 1 --------- Insufficient buffer length checking in user name canonicalization may allow attacker to execute arbitrary code on servers using Cyrus SASL library. Client side library also has the bug but since the user name is asked from the local user, there's probably not many applications that care about it, except maybe webmails and the like. This overflow only happens if default realm is set. Exploiting may not be too easy though, since you can only write "@default.realm.name" to limited space in heap past the buffer, depending on how long user name is allowed. With postfix this is around 2048 BASE64 encoded bytes (around 1500 bytes) by default. Postfix uses $myhostname as default realm name. We can overflow two different buffers at the end of sasl_conn_t structure: char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1]; sasl_conn_t is malloc()ed, so the most obvious exploit could happen with modifying malloc headers. Since we can use only few specific characters, the possibility to exploit is very system dependant. Problem 2 --------- LDAP authentication with saslauthd doesn't allocate enough memory when it needs to escape characters '*', '(', ')', '\' and '\0' in username and realm. This should be easily exploited with glibc's malloc implementation. Problem 3 --------- Log writer might not have allocated memory for the trailing \0 in message. Probably hard to exploit, although you can affect the logging data with at least anonymous authentication. patch ----- If you need for some reason. diff -ru cyrus-sasl-2.1.9-old/lib/canonusr.c cyrus-sasl-2.1.9/lib/canonusr.c --- cyrus-sasl-2.1.9-old/lib/canonusr.c 2002-09-16 21:37:20.000000000 +0300 +++ cyrus-sasl-2.1.9/lib/canonusr.c 2002-12-05 06:18:36.000000000 +0200 @@ -306,6 +306,7 @@ /* Now copy! (FIXME: check for SASL_BUFOVER?) */ memcpy(out_user, begin_u, MIN(ulen, out_umax)); if(sconn && u_apprealm) { + if(ulen >= out_umax) return SASL_BUFOVER; out_user[ulen] = '@'; memcpy(&(out_user[ulen+1]), sconn->user_realm, MIN(u_apprealm-1, out_umax-ulen-1)); diff -ru cyrus-sasl-2.1.9-old/saslauthd/lak.c cyrus-sasl-2.1.9/saslauthd/lak.c --- cyrus-sasl-2.1.9-old/saslauthd/lak.c 2002-08-01 22:58:24.000000000 +0300 +++ cyrus-sasl-2.1.9/saslauthd/lak.c 2002-12-05 07:43:34.000000000 +0200 @@ -279,7 +279,7 @@ char *buf; char *end, *ptr, *temp; - buf = malloc(strlen(s) * 2 + 1); + buf = malloc(strlen(s) * 3 + 1); if (buf == NULL) { return LAK_NOMEM; } @@ -358,7 +358,8 @@ if( *buf == '%' ) percents++; } - buf=malloc(strlen(lak->conf->filter) + (percents * maxparamlength) +1); + buf=malloc(strlen(lak->conf->filter) + + (percents * maxparamlength * 3) + 1); if(buf == NULL) { syslog(LOG_ERR|LOG_AUTH, "Cannot allocate memory"); return LAK_NOMEM; diff -ru cyrus-sasl-2.1.9-old/lib/common.c cyrus-sasl-2.1.9/lib/common.c --- cyrus-sasl-2.1.9-old/lib/common.c 2002-09-19 01:07:54.000000000 +0300 +++ cyrus-sasl-2.1.9/lib/common.c 2002-12-05 08:11:49.000000000 +0200 @@ -1326,6 +1326,8 @@ } } + result = _buf_alloc(&out, &alloclen, outlen+1); + if (result != SASL_OK) goto done; out[outlen]=0; /* put 0 at end */ va_end(ap);