A heap-based buffer overflow flaw was reported in the mutt_substrdup() function in Mutt. Opening a specially-crafted mail message could cause mutt to crash or, potentially, execute arbitrary code.
In testing on Fedora, "set weed=no" had to be set in the user's .muttrc before the issue presented.
Created mutt tracking bugs for this issue:
Affects: fedora-all [bug 1168464]
MITRE assigned CVE-2014-9116 to this issue:
(In reply to Murray McAllister from comment #0)
> A heap-based buffer overflow flaw was reported in the mutt_substrdup()
> function in Mutt.
I would not call it a flaw in mutt_substrdup(), but rather in a caller that passes end < begin to mutt_substrdup(). In this case, it's write_one_header(). It seems this code had several problems in the past.
The version of mutt as shipped with Red Hat Enterprise Linux 6 crashes on the mailbox from the original Debian bug report:
However, the cause is different from the cause of crash in more recent mutt versions. The mutt version in Red Hat Enterprise Linux 6 did not properly check if mail header contains ':' separator, which could cause a NULL pointer dereference (actually, 0x2 pointer is passed to mutt_substrdup() as begin). This makes mutt_substrdup() write (memcpy) near NULL, causing mutt to crash.
The code is:
1787 t = strchr (start, ':');
1788 if (t > end)
1790 dprint (1, (debugfile, "mwoh: warning: header not in "
1791 "'key: value' format!\n"));
1792 return 0;
1801 tagbuf = mutt_substrdup (start, t);
1802 valbuf = mutt_substrdup (t + 2, end);
Upstream bug and commit that added t != NULL check:
At some point (but before the above t != NULL check was added), the code was changed to not use static t+2 to point to the header value, but skip zero or more white spaces after ':'. Upstream bug and commit:
The version of mutt as shipped in Red Hat Enterprise Linux 7 has the both above changes, so the code looks as:
1801 t = strchr (start, ':');
1802 if (t == NULL || t > end)
1804 dprint (1, (debugfile, "mwoh: warning: header not in "
1805 "'key: value' format!\n"));
1806 return 0;
1815 tagbuf = mutt_substrdup (start, t);
1816 ++t; /* skip over the colon separating the header field name and value */
1817 SKIPWS(t); /* skip over any leading whitespace */
1818 valbuf = mutt_substrdup (t, end);
and SKIPWS is:
83 # define SKIPWS(c) while (*(c) && isspace ((unsigned char) *(c))) c++;
As this skips newlines, it can lead to mutt_substrdup() called with end < begin. The problem was already reported upstream and fixed by changing the code to only skip space and tab, but not newlines:
Apparently, the fix was regressed when skip_email_wsp() was added, which made write_one_header() skip newlines again:
The impact of this problem is limited to crash. This is what mutt_substrdup() does:
814 size_t len;
815 char *p;
817 if (end)
818 len = end - begin;
820 len = strlen (begin);
822 p = safe_malloc (len + 1);
823 memcpy (p, begin, len);
The mailbox file form the Debian bug causes mutt_substrdup() to be called with begin = end + 1, leading to len being SIZE_MAX. safe_malloc() is called with size 0, which makes it return NULL. The memcpy() called next attempts to write to memory starting at NULL, which leads to crash.
It is possible to adjust the mailbox to use begin = end + 2 (or more). That would lead to safe_malloc() called with size that is near SIZE_MAX. Such allocation does not succeed and causes mutt to abort with "Out of memory!" error. If changed to use begin = end + n, where n is large enough to not trigger memory allocation failure, there will be no buffer over write, but likely a buffer over read, which is likely to trigger mutt crash. There may be limits elsewhere in the code making it impossible to make n large enough.
Created upstream ticket:
for me it crashes even with "set weed=yes"
Don't think that a segfault is low priority.
noticed that with my settings the crash happens only when looking at the headers with "h". So weed=yes will help only as long as nobody looks at the header at best.
Fixed upstream now via:
The fix reverts the change applied via f251d523ca5a (see comment 4 above).