Fwd: report 1/3: buffer under-read in rfc2047.c lwslen()
"Kevin J. McCarthy" <[email protected]> Thu, 18 Jun 2026 08:09:01 +0800
| Newsgroups | gmane.mail.mutt.devel |
|---|---|
| Message-ID | <[email protected]> |
----- Forwarded message from Acts1631 <[email protected]> ----- Date: Wed, 17 Jun 2026 20:15:06 +0000 From: Acts1631 <[email protected]> To: "[email protected]" <[email protected]> Subject: report 1/3: buffer under-read in rfc2047.c lwslen() X-Spam-score: 0.0 X-Delivered-to: [email protected] Message-ID: <KB1oAIhwdCCndxRC7kVDWhJwXFMiK_E4A1Rr0WtQC3oDqkYPf6QD03ytEi_v2em8t8G3YKXEM_U5PYaYGijG4BPSorlrytsZh79CIJT6t7U=@proton.me> Hi again sir. Thanks for taking my earlier bug. I have 3 more for you to consider. Each one has a proposed patch and reproducer. Here's the first one. The lwslen() helper calculates the length of linear whitespace at the beginning of a string. It scans until the first non-whitespace character, then evaluates *(p - 1): for (; p < s + n; p++) if (!strchr(" \t\r\n", *p)) { len = (size_t)(p - s); break; } if (strchr("\r\n", *(p-1))) len = (size_t)0; If the string starts with a non-whitespace character, the loop breaks on its first iteration with p == s and len == 0. The subsequent *(p - 1) read accesses one byte before the buffer. This is reachable through rfc2047_decode() when ignore_linear_white_space is enabled and lwslen() is called on text following an encoded word. Example trigger subject: Subject: =?utf-8?Q?foo?=bar After decoding the encoded word, rfc2047_decode() sees the trailing "bar", sets found_encoded, and calls lwslen("bar", 3). The first character is not whitespace, so the under-read occurs in the unpatched code. Proposed fix: Guard the final look-behind with len > 0: if (len > 0 && strchr("\r\n", *(p-1))) len = (size_t)0; When len > 0, p has advanced beyond s, so p - 1 is guaranteed to be in bounds. When len == 0, the CR/LF check cannot change the return value and can be safely skipped. ----- End forwarded message ----- -- Kevin J. McCarthy GPG Fingerprint: 8975 A9B3 3AA3 7910 385C 5308 ADEF 7684 8031 6BDA
bug1.patch
(text/x-patch, 406 B)
diff --git a/rfc2047.c b/rfc2047.c
index d72ae997..2bdd8553 100644
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -815,7 +815,7 @@ static size_t lwslen(const char *s, size_t n)
len = (size_t)(p - s);
break;
}
- if (strchr("\r\n", *(p-1))) /* LWS doesn't end with CRLF */
+ if (len > 0 && strchr("\r\n", *(p-1))) /* LWS doesn't end with CRLF */
len = (size_t)0;
return len;
}
bug1_reproducer.py
(text/x-python, 1 KB)
#!/usr/bin/env python3
"""
Reproducer for Bug 1: rfc2047.c lwslen() buffer under-read.
This emits an mbox message whose Subject has trailing non-whitespace text
after an RFC2047 encoded word:
Subject: =?utf-8?Q?foo?=bar
In rfc2047_decode(), once an encoded word has been found,
ignore_linear_white_space makes mutt call lwslen() on the trailing "bar".
The first byte is not whitespace, so the unpatched lwslen() reads one byte
before the buffer via *(p - 1).
Example:
python3 reproducer_lwslen.py > /tmp/lwslen.mbox
mutt -e 'set ignore_linear_white_space' -f /tmp/lwslen.mbox
Use an AddressSanitizer build to make the one-byte under-read visible.
"""
email = """\
From [email protected] Wed Jun 17 00:00:00 2026
From: [email protected]
To: [email protected]
Subject: =?utf-8?Q?foo?=bar
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
This message triggers lwslen() on trailing non-whitespace text when
ignore_linear_white_space is enabled.
"""
if __name__ == "__main__":
print(email)
signature.asc
(application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEiXWpszqjeRA4XFMIre92hIAxa9oFAmozNx0ACgkQre92hIAx a9rVfg//W++Ja/u5lh1SWKwCHAzyr7CgRo8lEXvmqORpEGjOBODNiicCuWWKJCER mRSsDbxWjFFY84AaQIK8b+sV+0SoiqTXPLtOVOfajY2fmeYbH80a9ZA0tZEo4yOS P5FWy+Rx2vH0d5yqnVBSejBidVmkH4WTHC7018a3WVOn583X4bs5Ag8rSKhSQ2fq LLBXSWLfTjKn3Bwv/Bp+v4snbXfQidj0iHEe6iSd32BGrY74I51/FNaH+gW2Ygwk xIcaUJ9TvKS8/2p/zB/HVZsSnQfR96TdTPxLQAigMmIhzgqmngn0hjZJFSm/bZcq UtTr4kCMRSQoTC/5JRZ8AAmnnIjDabnvpuNWG3kIv+listPJa7r27PetkfV28qvQ HbfKezmv0DqCTwjhRXWCRtDs/ImMAVXa+gwOxbJ77rypKQi+ZZa9kb+ns5nV9qP9 wkPhrG2fKCt1DcbMfRqj/UqfXqzK2aE8+r1agrpL1w+kEx7UWHGTnokYdayi7tHg 7WU5OWPJDxJVKwlrbARXQBWvIboteZjvNUQWV+MtOgWmb2qhjAZ+qaHmP+TlXOT/ po7RTUunX+YUoLNoedy1HmFOOdzDTda3FjH1L2y2AAci9lrtSYmlGE9zJCqEQbFQ BtMl4sjylgvn1+stg7JwAF9WF2nLcQVs2kPjtZBl34oFUDIsfto= =9fxh -----END PGP SIGNATURE-----