mailing list of musl libc
 help / color / mirror / Atom feed
* [musl] CVE-2020-28928: musl libc: wcsnrtombs destination buffer overflow
@ 2020-11-19 23:47 Rich Felker
  0 siblings, 0 replies; only message in thread
From: Rich Felker @ 2020-11-19 23:47 UTC (permalink / raw)
  To: musl, oss-security

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

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.

[-- Attachment #2: wcsnrtombs-cve-2020-28928.diff --]
[-- Type: text/plain, Size: 1372 bytes --]

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 <wchar.h>
+#include <limits.h>
+#include <string.h>
 
 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(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
+		if (l==-1) {
+			cnt = -1;
 			break;
 		}
-		if (s != buf) {
-			s += l;
+		if (dst) {
+			if (n<MB_LEN_MAX) {
+				if (l>n) 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;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-11-19 23:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-19 23:47 [musl] CVE-2020-28928: musl libc: wcsnrtombs destination buffer overflow Rich Felker

mailing list of musl libc

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://inbox.vuxu.org/musl

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V1 musl musl/ http://inbox.vuxu.org/musl \
		musl@inbox.vuxu.org
	public-inbox-index musl

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.musl


code repositories for the project(s) associated with this inbox:

	https://git.vuxu.org/mirror/musl/

AGPL code for this site: git clone https://public-inbox.org/public-inbox.git