From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 24867 invoked from network); 19 Nov 2020 23:47:42 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 19 Nov 2020 23:47:42 -0000 Received: (qmail 3644 invoked by uid 550); 19 Nov 2020 23:47:36 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 3622 invoked from network); 19 Nov 2020 23:47:35 -0000 Date: Thu, 19 Nov 2020 18:47:22 -0500 From: Rich Felker To: musl@lists.openwall.com, oss-security@lists.openwall.com Message-ID: <20201119234717.GA18029@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="6TrnltStXW4iwmi0" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Subject: [musl] CVE-2020-28928: musl libc: wcsnrtombs destination buffer overflow --6TrnltStXW4iwmi0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline The wcsnrtombs function in all musl libc versions up through 1.2.1 has been found to have multiple bugs in handling of destination buffer size when limiting the input character count, which can lead to infinite loop with no forward progress (no overflow) or writing past the end of the destination buffera. This function is not used internally in musl and is not widely used, but does appear in some applications. The non-input-limiting form wcsrtombs is not affected. All users of musl 1.2.1 and prior versions should apply the attached patch, which replaces the overly complex and erroneous implementation. The upcoming 1.2.2 release will adopt this new implementation. --6TrnltStXW4iwmi0 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="wcsnrtombs-cve-2020-28928.diff" diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c index 676932b5..95e25e70 100644 --- a/src/multibyte/wcsnrtombs.c +++ b/src/multibyte/wcsnrtombs.c @@ -1,41 +1,33 @@ #include +#include +#include size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st) { - size_t l, cnt=0, n2; - char *s, buf[256]; const wchar_t *ws = *wcs; - const wchar_t *tmp_ws; - - if (!dst) s = buf, n = sizeof buf; - else s = dst; - - while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) { - if (n2>=n) n2=n; - tmp_ws = ws; - l = wcsrtombs(s, &ws, n2, 0); - if (!(l+1)) { - cnt = l; - n = 0; + size_t cnt = 0; + if (!dst) n=0; + while (ws && wn) { + char tmp[MB_LEN_MAX]; + size_t l = wcrtomb(nn) break; + memcpy(dst, tmp, l); + } + dst += l; n -= l; } - wn = ws ? wn - (ws - tmp_ws) : 0; - cnt += l; - } - if (ws) while (n && wn) { - l = wcrtomb(s, *ws, 0); - if ((l+1)<=1) { - if (!l) ws = 0; - else cnt = l; + if (!*ws) { + ws = 0; break; } - ws++; wn--; - /* safe - this loop runs fewer than sizeof(buf) times */ - s+=l; n-=l; + ws++; + wn--; cnt += l; } if (dst) *wcs = ws; --6TrnltStXW4iwmi0--