From b678b53fcab441a297bd1f1c323fe14298450ef9 Mon Sep 17 00:00:00 2001
From: Max Rees <maxcrees@me.com>
Date: Thu, 19 Nov 2020 20:38:14 -0500
Subject: system/musl: patch CVE-2020-28928

---
 system/musl/APKBUILD             |   6 ++-
 system/musl/CVE-2020-28928.patch | 112 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 system/musl/CVE-2020-28928.patch

(limited to 'system')

diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
index 8517b148b..735541e51 100644
--- a/system/musl/APKBUILD
+++ b/system/musl/APKBUILD
@@ -1,7 +1,7 @@
 # Maintainer: A. Wilcox <awilfox@adelielinux.org>
 pkgname=musl
 pkgver=1.2.0
-pkgrel=1
+pkgrel=2
 pkgdesc="System library (libc) implementation"
 url="https://www.musl-libc.org/"
 arch="all"
@@ -27,6 +27,7 @@ source="https://musl.libc.org/releases/$pkgname-$pkgver.tar.gz
 	handle-aux-at_base.patch
 	fgetspent_r.patch
 	threads_minus_1.patch
+	CVE-2020-28928.patch
 
 	ldconfig
 	getent.c
@@ -38,6 +39,8 @@ source="https://musl.libc.org/releases/$pkgname-$pkgver.tar.gz
 #     - CVE-2016-8859
 #   1.1.23-r2:
 #     - CVE-2019-14697
+#   1.2.0-r2:
+#     - CVE-2020-28928
 
 build() {
 	[ "$BOOTSTRAP" = "nocc" ] && return 0
@@ -123,6 +126,7 @@ f01ab92b9d385c15369c0bb7d95e1bc06a009c8851e363517d0ba1bae3fc2647af69fc2f363b5d96
 6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238  handle-aux-at_base.patch
 ded41235148930f8cf781538f7d63ecb0c65ea4e8ce792565f3649ee2523592a76b2a166785f0b145fc79f5852fd1fb1729a7a09110b3b8f85cba3912e790807  fgetspent_r.patch
 68830961e297d9a499f3b609be84848ad5d3326a1af56e9e54a40ecd972c48da11532c51da572d45e0df3574d63191e7ae0d3a1b84a029365f8d00691de96952  threads_minus_1.patch
+343ac5e5365cf98a5d5b7bc192c671733fdba27f06b83484f1ac7647154228745415f62dd676029de538460f8b35e0a70ca453a0f8b73226ed1c420099b1cf90  CVE-2020-28928.patch
 cb71d29a87f334c75ecbc911becde7be825ab30d8f39fa6d64cb53812a7c9abaf91d9804c72540e5be3ddd3c84cfe7fd9632274309005cb8bcdf9a9b09b4b923  ldconfig
 378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413  getent.c
 9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf  iconv.c"
diff --git a/system/musl/CVE-2020-28928.patch b/system/musl/CVE-2020-28928.patch
new file mode 100644
index 000000000..cc668e149
--- /dev/null
+++ b/system/musl/CVE-2020-28928.patch
@@ -0,0 +1,112 @@
+From 3ab2a4e02682df1382955071919d8aa3c3ec40d4 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Thu, 19 Nov 2020 17:12:43 -0500
+Subject: [PATCH] rewrite wcsnrtombs to fix buffer overflow and other bugs
+
+the original wcsnrtombs implementation, which has been largely
+untouched since 0.5.0, attempted to build input-length-limiting
+conversion on top of wcsrtombs, which only limits output length. as
+best I recall, this choice was made out of a mix of disdain over
+having yet another variant function to implement (added in POSIX 2008;
+not standard C) and preference not to switch things around and
+implement the wcsrtombs in terms of the more general new function,
+probably over namespace issues. the strategy employed was to impose
+output limits that would ensure the input limit wasn't exceeded, then
+finish up the tail character-at-a-time. unfortunately, none of that
+worked correctly.
+
+first, the logic in the wcsrtombs loop was wrong in that it could
+easily get stuck making no forward progress, by imposing an output
+limit too small to convert even one character.
+
+the character-at-a-time loop that followed was even worse. it made no
+effort to ensure that the converted multibyte character would fit in
+the remaining output space, only that there was a nonzero amount of
+output space remaining. it also employed an incorrect interpretation
+of wcrtomb's interface contract for converting the null character,
+thereby failing to act on end of input, and remaining space accounting
+was subject to unsigned wrap-around. together these errors allow
+unbounded overflow of the destination buffer, controlled by input
+length limit and input wchar_t string contents.
+
+given the extent to which this function was broken, it's plausible
+that most applications that would have been rendered exploitable were
+sufficiently broken not to be usable in the first place. however, it's
+also plausible that common (especially ASCII-only) inputs succeeded in
+the wcsrtombs loop, which mostly worked, while leaving the wildly
+erroneous code in the second loop exposed to particular non-ASCII
+inputs.
+
+CVE-2020-28928 has been assigned for this issue.
+---
+ src/multibyte/wcsnrtombs.c | 46 ++++++++++++++++----------------------
+ 1 file changed, 19 insertions(+), 27 deletions(-)
+
+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;
+-- 
+2.25.4
+
-- 
cgit v1.2.3-70-g09d2