[openwrt/openwrt] musl: handle wcsnrtombs destination buffer overflow (CVE-2020-28928)

LEDE Commits lede-commits at lists.infradead.org
Mon Nov 23 16:47:55 EST 2020


ynezz pushed a commit to openwrt/openwrt.git, branch openwrt-19.07:
https://git.openwrt.org/733a48273383e2337fcd7c0eb5ee8958f42dc4c0

commit 733a48273383e2337fcd7c0eb5ee8958f42dc4c0
Author: Petr Štetiar <ynezz at true.cz>
AuthorDate: Fri Nov 20 13:13:27 2020 +0100

    musl: handle wcsnrtombs destination buffer overflow (CVE-2020-28928)
    
    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.
    
    Signed-off-by: Petr Štetiar <ynezz at true.cz>
    (cherry picked from commit 4d4ef1058c0f10aa2fa4070cd6b9db4d48b94148)
---
 toolchain/musl/common.mk                           |  2 +-
 .../patches/700-wcsnrtombs-cve-2020-28928.diff     | 65 ++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/toolchain/musl/common.mk b/toolchain/musl/common.mk
index bb9d9a75a5..522fda4b92 100644
--- a/toolchain/musl/common.mk
+++ b/toolchain/musl/common.mk
@@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/target.mk
 
 PKG_NAME:=musl
 PKG_VERSION:=1.1.24
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
diff --git a/toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff b/toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
new file mode 100644
index 0000000000..8465f9422a
--- /dev/null
+++ b/toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
@@ -0,0 +1,65 @@
+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;



More information about the lede-commits mailing list