commit:     8a8e70b0165c61ec95464968205a8cf06859e607
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 24 14:59:52 2020 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Nov 24 14:59:59 2020 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8a8e70b0

sys-libs/musl: security bump for CVE-2020-28928

Acked-by: Anthony G. Basile <blueness <AT> gentoo.org>
Bug: https://bugs.gentoo.org/755695
Package-Manager: Portage-3.0.9, Repoman-3.0.2
Signed-off-by: Sam James <sam <AT> gentoo.org>

 .../musl/files/musl-1.2.1-CVE-2020-28928.patch     | 114 ++++++++++++++++++
 sys-libs/musl/musl-1.2.1-r1.ebuild                 | 133 +++++++++++++++++++++
 2 files changed, 247 insertions(+)

diff --git a/sys-libs/musl/files/musl-1.2.1-CVE-2020-28928.patch 
b/sys-libs/musl/files/musl-1.2.1-CVE-2020-28928.patch
new file mode 100644
index 00000000000..9797e92ec42
--- /dev/null
+++ b/sys-libs/musl/files/musl-1.2.1-CVE-2020-28928.patch
@@ -0,0 +1,114 @@
+https://bugs.gentoo.org/755695
+https://git.musl-libc.org/cgit/musl/patch/?id=3ab2a4e02682df1382955071919d8aa3c3ec40d4
+From 3ab2a4e02682df1382955071919d8aa3c3ec40d4 Mon Sep 17 00:00:00 2001
+From: Rich Felker <[email protected]>
+Date: Thu, 19 Nov 2020 17:12:43 -0500
+Subject: 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;
+-- 
+cgit v1.2.1
+

diff --git a/sys-libs/musl/musl-1.2.1-r1.ebuild 
b/sys-libs/musl/musl-1.2.1-r1.ebuild
new file mode 100644
index 00000000000..05a55e96e2d
--- /dev/null
+++ b/sys-libs/musl/musl-1.2.1-r1.ebuild
@@ -0,0 +1,133 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit eutils flag-o-matic multilib toolchain-funcs
+if [[ ${PV} == "9999" ]] ; then
+       EGIT_REPO_URI="git://git.musl-libc.org/musl"
+       inherit git-r3
+       SRC_URI="
+       https://dev.gentoo.org/~blueness/musl-misc/getconf.c
+       https://dev.gentoo.org/~blueness/musl-misc/getent.c
+       https://dev.gentoo.org/~blueness/musl-misc/iconv.c";
+       KEYWORDS=""
+else
+       SRC_URI="http://www.musl-libc.org/releases/${P}.tar.gz
+       https://dev.gentoo.org/~blueness/musl-misc/getconf.c
+       https://dev.gentoo.org/~blueness/musl-misc/getent.c
+       https://dev.gentoo.org/~blueness/musl-misc/iconv.c";
+       KEYWORDS="-* ~amd64 ~arm ~arm64 ~mips ~ppc ~ppc64 ~x86"
+fi
+
+export CBUILD=${CBUILD:-${CHOST}}
+export CTARGET=${CTARGET:-${CHOST}}
+if [[ ${CTARGET} == ${CHOST} ]] ; then
+       if [[ ${CATEGORY} == cross-* ]] ; then
+               export CTARGET=${CATEGORY#cross-}
+       fi
+fi
+
+DESCRIPTION="Light, fast and simple C library focused on standards-conformance 
and safety"
+HOMEPAGE="http://www.musl-libc.org/";
+LICENSE="MIT LGPL-2 GPL-2"
+SLOT="0"
+IUSE="headers-only"
+
+QA_SONAME="/usr/lib/libc.so"
+QA_DT_NEEDED="/usr/lib/libc.so"
+
+PATCHES=(
+       "${FILESDIR}/${P}-CVE-2020-28928.patch"
+)
+
+is_crosscompile() {
+       [[ ${CHOST} != ${CTARGET} ]]
+}
+
+just_headers() {
+       use headers-only && is_crosscompile
+}
+
+pkg_setup() {
+       if [ ${CTARGET} == ${CHOST} ] ; then
+               case ${CHOST} in
+               *-musl*) ;;
+               *) die "Use sys-devel/crossdev to build a musl toolchain" ;;
+               esac
+       fi
+
+       # fix for #667126, copied from glibc ebuild
+       # make sure host make.conf doesn't pollute us
+       if is_crosscompile || tc-is-cross-compiler ; then
+               CHOST=${CTARGET} strip-unsupported-flags
+       fi
+}
+
+src_configure() {
+       tc-getCC ${CTARGET}
+       just_headers && export CC=true
+
+       local sysroot
+       is_crosscompile && sysroot=/usr/${CTARGET}
+       ./configure \
+               --target=${CTARGET} \
+               --prefix=${sysroot}/usr \
+               --syslibdir=${sysroot}/lib \
+               --disable-gcc-wrapper || die
+}
+
+src_compile() {
+       emake obj/include/bits/alltypes.h
+       just_headers && return 0
+
+       emake
+       if [[ ${CATEGORY} != cross-* ]] ; then
+               emake -C "${T}" getconf getent iconv \
+                       CC="$(tc-getCC)" \
+                       CFLAGS="${CFLAGS}" \
+                       CPPFLAGS="${CPPFLAGS}" \
+                       LDFLAGS="${LDFLAGS}" \
+                       VPATH="${DISTDIR}"
+       fi
+}
+
+src_install() {
+       local target="install"
+       just_headers && target="install-headers"
+       emake DESTDIR="${D}" ${target}
+       just_headers && return 0
+
+       # musl provides ldd via a sym link to its ld.so
+       local sysroot
+       is_crosscompile && sysroot=/usr/${CTARGET}
+       local ldso=$(basename "${D}"${sysroot}/lib/ld-musl-*)
+       dosym ${sysroot}/lib/${ldso} ${sysroot}/usr/bin/ldd
+
+       if [[ ${CATEGORY} != cross-* ]] ; then
+               # Fish out of config:
+               #   ARCH = ...
+               #   SUBARCH = ...
+               # and print $(ARCH)$(SUBARCH).
+               local arch=$(awk '{ k[$1] = $3 } END { printf("%s%s", 
k["ARCH"], k["SUBARCH"]); }' config.mak)
+               [[ -e "${D}"/lib/ld-musl-${arch}.so.1 ]] || die
+               cp "${FILESDIR}"/ldconfig.in "${T}" || die
+               sed -e "s|@@ARCH@@|${arch}|" "${T}"/ldconfig.in > 
"${T}"/ldconfig || die
+               into /
+               dosbin "${T}"/ldconfig
+               into /usr
+               dobin "${T}"/getconf
+               dobin "${T}"/getent
+               dobin "${T}"/iconv
+               echo 'LDPATH="include ld.so.conf.d/*.conf"' > "${T}"/00musl || 
die
+               doenvd "${T}"/00musl
+       fi
+}
+
+pkg_postinst() {
+       is_crosscompile && return 0
+
+       [ "${ROOT}" != "/" ] && return 0
+
+       ldconfig || die
+}

Reply via email to