aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
diff options
context:
space:
mode:
authorPetr Štetiar <ynezz@true.cz>2020-11-20 13:13:27 +0100
committerPetr Štetiar <ynezz@true.cz>2020-11-20 13:24:48 +0100
commit4d4ef1058c0f10aa2fa4070cd6b9db4d48b94148 (patch)
treee4cf5882e4101c4f7f223e76e133906d4b29a14d /toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff
parentd36999389890fb952fc7cc8c0db8e1bbb671af12 (diff)
downloadupstream-4d4ef1058c0f10aa2fa4070cd6b9db4d48b94148.tar.gz
upstream-4d4ef1058c0f10aa2fa4070cd6b9db4d48b94148.tar.bz2
upstream-4d4ef1058c0f10aa2fa4070cd6b9db4d48b94148.zip
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@true.cz>
Diffstat (limited to 'toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff')
-rw-r--r--toolchain/musl/patches/700-wcsnrtombs-cve-2020-28928.diff65
1 files changed, 65 insertions, 0 deletions
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;