From: Kevin McCarthy Date: Wed, 30 Sep 2015 03:21:06 +0000 (+0800) Subject: Fix oob reads when fgets returns "\0". (closes #3776) X-Git-Tag: mutt-1-6-1-rel~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d01674782ba0228182e310b1bdfb086a25e8c7db;p=mutt Fix oob reads when fgets returns "\0". (closes #3776) The ticket reported an out of bounds read in mutt_read_rfc822_line() when a '\0' was embedded on its own line in the headers. The function assumed if fgets() didn't return NULL, then the string would have at least one character. I scanned the rest of the code and found three other places making the same assumption for fgets. Thanks to hanno for finding this with the "american fuzzy lop" tool. --- diff --git a/parse.c b/parse.c index 58c77747..3098cae3 100644 --- a/parse.c +++ b/parse.c @@ -43,6 +43,7 @@ char *mutt_read_rfc822_line (FILE *f, char *line, size_t *linelen) char *buf = line; int ch; size_t offset = 0; + size_t len = 0; FOREVER { @@ -53,7 +54,11 @@ char *mutt_read_rfc822_line (FILE *f, char *line, size_t *linelen) return (line); } - buf += strlen (buf) - 1; + len = mutt_strlen (buf); + if (! len) + return (line); + + buf += len - 1; if (*buf == '\n') { /* we did get a full line. remove trailing space */ diff --git a/smime.c b/smime.c index eebde562..72047bce 100644 --- a/smime.c +++ b/smime.c @@ -915,6 +915,7 @@ static int smime_handle_cert_email (char *certificate, char *mailbox, char email[STRING]; int ret = -1, count = 0; pid_t thepid; + size_t len = 0; mutt_mktemp (tmpfname, sizeof (tmpfname)); if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) @@ -954,7 +955,9 @@ static int smime_handle_cert_email (char *certificate, char *mailbox, while ((fgets (email, sizeof (email), fpout))) { - *(email + mutt_strlen (email)-1) = '\0'; + len = mutt_strlen (email); + if (len) + *(email + len - 1) = '\0'; if(mutt_strncasecmp (email, mailbox, mutt_strlen (mailbox)) == 0) ret=1; @@ -982,7 +985,9 @@ static int smime_handle_cert_email (char *certificate, char *mailbox, rewind (fpout); while ((fgets (email, sizeof (email), fpout))) { - *(email + mutt_strlen (email) - 1) = '\0'; + len = mutt_strlen (email); + if (len) + *(email + len - 1) = '\0'; (*buffer)[count] = safe_calloc(1, mutt_strlen (email) + 1); strncpy((*buffer)[count], email, mutt_strlen (email)); count++; diff --git a/smtp.c b/smtp.c index a718006b..03054b4b 100644 --- a/smtp.c +++ b/smtp.c @@ -200,9 +200,8 @@ smtp_data (CONNECTION * conn, const char *msgfile) while (fgets (buf, sizeof (buf) - 1, fp)) { buflen = mutt_strlen (buf); - term = buf[buflen-1] == '\n'; - if (buflen && buf[buflen-1] == '\n' - && (buflen == 1 || buf[buflen - 2] != '\r')) + term = buflen && buf[buflen-1] == '\n'; + if (term && (buflen == 1 || buf[buflen - 2] != '\r')) snprintf (buf + buflen - 1, sizeof (buf) - buflen + 1, "\r\n"); if (buf[0] == '.') {