# Merge from clamav-devel to fix decodeLine bug # See http://www.freebsd.org/cgi/query-pr.cgi?pr=62586 # -- Rui Lopes --- libclamav/message.c.orig Mon Feb 9 23:00:04 2004 +++ libclamav/message.c Mon Feb 9 23:04:40 2004 @@ -74,7 +74,7 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; -static unsigned char *decodeLine(const message *m, const char *line, unsigned char *ptr); +static unsigned char *decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen); static unsigned char *decode(const char *in, unsigned char *out, unsigned char (*decoder)(char), bool isFast); static unsigned char hex(char c); static unsigned char base64(char c); @@ -273,7 +273,7 @@ if(offset == m->numberOfArguments) { m->numberOfArguments++; - m->mimeArguments = (char **)realloc(m->mimeArguments, m->numberOfArguments * sizeof(char *)); + m->mimeArguments = (char **)cli_realloc(m->mimeArguments, m->numberOfArguments * sizeof(char *)); } m->mimeArguments[offset] = strdup(arg); @@ -658,7 +658,7 @@ if(strcasecmp(line, "end") == 0) break; - uptr = decodeLine(m, line, data); + uptr = decodeLine(m, line, data, sizeof(data)); if(uptr == NULL) break; @@ -737,7 +737,7 @@ if(strcasecmp(line, "end") == 0) break; - uptr = decodeLine(m, line, data); + uptr = decodeLine(m, line, data, sizeof(data)); if(uptr == NULL) break; @@ -798,24 +798,24 @@ * to help appending callers. There is no new line at the end of "line" */ static unsigned char * -decodeLine(const message *m, const char *line, unsigned char *ptr) +decodeLine(const message *m, const char *line, unsigned char *buf, size_t buflen) { - int len; + size_t len; bool softbreak; char *p2; char *copy; assert(m != NULL); assert(line != NULL); - assert(ptr != NULL); + assert(buf != NULL); switch(messageGetEncoding(m)) { case NOENCODING: case EIGHTBIT: default: /* unknown encoding type - try our best */ - ptr = (unsigned char *)strrcpy((char *)ptr, line); + buf = (unsigned char *)strrcpy((char *)buf, line); /* Put the new line back in */ - return (unsigned char *)strrcpy((char *)ptr, "\n"); + return (unsigned char *)strrcpy((char *)buf, "\n"); case QUOTEDPRINTABLE: softbreak = FALSE; @@ -836,20 +836,20 @@ * broken e-mail, not * adhering to RFC1522 */ - *ptr++ = byte; + *buf++ = byte; break; } byte <<= 4; byte += hex(*line); - *ptr++ = byte; + *buf++ = byte; } else - *ptr++ = *line; + *buf++ = *line; line++; } if(!softbreak) /* Put the new line back in */ - *ptr++ = '\n'; + *buf++ = '\n'; break; case BASE64: @@ -864,8 +864,8 @@ /* * Klez doesn't always put "=" on the last line */ - /*ptr = decode(line, ptr, base64, p2 == NULL);*/ - ptr = decode(copy, ptr, base64, 0); + /*buf = decode(line, buf, base64, p2 == NULL);*/ + buf = decode(copy, buf, base64, 0); free(copy); break; @@ -878,15 +878,20 @@ if(strcasecmp(line, "end") == 0) break; - assert(strlen(line) <= 62); if((line[0] & 0x3F) == ' ') break; len = *line++ - ' '; - assert((len >= 0) && (len <= 63)); - - ptr = decode(line, ptr, uudecode, (len & 3) == 0); + if(len > buflen) + /* + * In practice this should never occur since + * the maximum length of a uuencoded line is + * 62 characters + */ + cli_warnmsg("uudecode: buffer overflow stopped, attempting to ignore but decoding may fail"); + else + buf = decode(line, buf, uudecode, (len & 3) == 0); break; case BINARY: @@ -896,8 +901,8 @@ break; } - *ptr = '\0'; - return ptr; + *buf = '\0'; + return buf; } static unsigned char *