public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Andreas Sturmlechner" <asturm@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-libs/icu/, dev-libs/icu/files/
Date: Wed, 18 May 2022 11:13:07 +0000 (UTC)	[thread overview]
Message-ID: <1652872373.3d3cad32d1310cafeeed46b374ef3120c0195ff7.asturm@gentoo> (raw)

commit:     3d3cad32d1310cafeeed46b374ef3120c0195ff7
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Wed May 18 10:54:00 2022 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Wed May 18 11:12:53 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3d3cad32

dev-libs/icu: Fix CVE-2022-1638

Bug: https://bugs.gentoo.org/843731
Package-Manager: Portage-3.0.30, Repoman-3.0.3
Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>

 dev-libs/icu/files/icu-71.1-CVE-2022-1638.patch | 202 ++++++++++++++++++++++++
 dev-libs/icu/icu-71.1-r1.ebuild                 | 154 ++++++++++++++++++
 2 files changed, 356 insertions(+)

diff --git a/dev-libs/icu/files/icu-71.1-CVE-2022-1638.patch b/dev-libs/icu/files/icu-71.1-CVE-2022-1638.patch
new file mode 100644
index 000000000000..216ed7894473
--- /dev/null
+++ b/dev-libs/icu/files/icu-71.1-CVE-2022-1638.patch
@@ -0,0 +1,202 @@
+From e96e9410bde06962c211fa6f21c3d91263a90f86 Mon Sep 17 00:00:00 2001
+From: Frank Tang <ftang@chromium.org>
+Date: Fri, 29 Apr 2022 22:50:33 +0000
+Subject: [PATCH] ICU-22005 Fix int32 overflow in FormattedStringBuilder
+
+See #2070
+---
+ .../i18n/formatted_string_builder.cpp  | 55 +++++++++++++------
+ .../formatted_string_builder_test.cpp         | 41 ++++++++++++++
+ 2 files changed, 79 insertions(+), 17 deletions(-)
+
+diff --git a/i18n/formatted_string_builder.cpp b/i18n/formatted_string_builder.cpp
+index 734078644b8..628fbea8711 100644
+--- a/i18n/formatted_string_builder.cpp
++++ b/i18n/formatted_string_builder.cpp
+@@ -6,6 +6,7 @@
+ #if !UCONFIG_NO_FORMATTING
+ 
+ #include "formatted_string_builder.h"
++#include "putilimp.h"
+ #include "unicode/ustring.h"
+ #include "unicode/utf16.h"
+ #include "unicode/unum.h" // for UNumberFormatFields literals
+@@ -197,6 +198,9 @@ FormattedStringBuilder::splice(int32_t startThis, int32_t endThis,  const Unicod
+     int32_t thisLength = endThis - startThis;
+     int32_t otherLength = endOther - startOther;
+     int32_t count = otherLength - thisLength;
++    if (U_FAILURE(status)) {
++        return count;
++    }
+     int32_t position;
+     if (count > 0) {
+         // Overall, chars need to be added.
+@@ -221,6 +225,9 @@ int32_t FormattedStringBuilder::append(const FormattedStringBuilder &other, UErr
+ 
+ int32_t
+ FormattedStringBuilder::insert(int32_t index, const FormattedStringBuilder &other, UErrorCode &status) {
++    if (U_FAILURE(status)) {
++        return 0;
++    }
+     if (this == &other) {
+         status = U_ILLEGAL_ARGUMENT_ERROR;
+         return 0;
+@@ -255,12 +262,18 @@ int32_t FormattedStringBuilder::prepareForInsert(int32_t index, int32_t count, U
+     U_ASSERT(index >= 0);
+     U_ASSERT(index <= fLength);
+     U_ASSERT(count >= 0);
++    U_ASSERT(fZero >= 0);
++    U_ASSERT(fLength >= 0);
++    U_ASSERT(getCapacity() - fZero >= fLength);
++    if (U_FAILURE(status)) {
++        return count;
++    }
+     if (index == 0 && fZero - count >= 0) {
+         // Append to start
+         fZero -= count;
+         fLength += count;
+         return fZero;
+-    } else if (index == fLength && fZero + fLength + count < getCapacity()) {
++    } else if (index == fLength && count <= getCapacity() - fZero - fLength) {
+         // Append to end
+         fLength += count;
+         return fZero + fLength - count;
+@@ -275,18 +288,26 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+     int32_t oldZero = fZero;
+     char16_t *oldChars = getCharPtr();
+     Field *oldFields = getFieldPtr();
+-    if (fLength + count > oldCapacity) {
+-        if ((fLength + count) > INT32_MAX / 2) {
+-            // If we continue, then newCapacity will overflow int32_t in the next line.
++    int32_t newLength;
++    if (uprv_add32_overflow(fLength, count, &newLength)) {
++        status = U_INPUT_TOO_LONG_ERROR;
++        return -1;
++    }
++    int32_t newZero;
++    if (newLength > oldCapacity) {
++        if (newLength > INT32_MAX / 2) {
++            // We do not support more than 1G char16_t in this code because
++            // dealing with >2G *bytes* can cause subtle bugs.
+             status = U_INPUT_TOO_LONG_ERROR;
+             return -1;
+         }
+-        int32_t newCapacity = (fLength + count) * 2;
+-        int32_t newZero = newCapacity / 2 - (fLength + count) / 2;
++        // Keep newCapacity also to at most 1G char16_t.
++        int32_t newCapacity = newLength * 2;
++        newZero = (newCapacity - newLength) / 2;
+ 
+         // C++ note: malloc appears in two places: here and in the assignment operator.
+-        auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * newCapacity));
+-        auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * newCapacity));
++        auto newChars = static_cast<char16_t *> (uprv_malloc(sizeof(char16_t) * static_cast<size_t>(newCapacity)));
++        auto newFields = static_cast<Field *>(uprv_malloc(sizeof(Field) * static_cast<size_t>(newCapacity)));
+         if (newChars == nullptr || newFields == nullptr) {
+             uprv_free(newChars);
+             uprv_free(newFields);
+@@ -315,10 +336,8 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+         fChars.heap.capacity = newCapacity;
+         fFields.heap.ptr = newFields;
+         fFields.heap.capacity = newCapacity;
+-        fZero = newZero;
+-        fLength += count;
+     } else {
+-        int32_t newZero = oldCapacity / 2 - (fLength + count) / 2;
++        newZero = (oldCapacity - newLength) / 2;
+ 
+         // C++ note: memmove is required because src and dest may overlap.
+         // First copy the entire string to the location of the prefix, and then move the suffix
+@@ -331,18 +350,20 @@ int32_t FormattedStringBuilder::prepareForInsertHelper(int32_t index, int32_t co
+         uprv_memmove2(oldFields + newZero + index + count,
+                 oldFields + newZero + index,
+                 sizeof(Field) * (fLength - index));
+-
+-        fZero = newZero;
+-        fLength += count;
+     }
+-    U_ASSERT((fZero + index) >= 0);
++    fZero = newZero;
++    fLength = newLength;
+     return fZero + index;
+ }
+ 
+ int32_t FormattedStringBuilder::remove(int32_t index, int32_t count) {
+-    // TODO: Reset the heap here?  (If the string after removal can fit on stack?)
++     U_ASSERT(0 <= index);
++     U_ASSERT(index <= fLength);
++     U_ASSERT(count <= (fLength - index));
++     U_ASSERT(index <= getCapacity() - fZero);
++
+     int32_t position = index + fZero;
+-    U_ASSERT(position >= 0);
++    // TODO: Reset the heap here?  (If the string after removal can fit on stack?)
+     uprv_memmove2(getCharPtr() + position,
+             getCharPtr() + position + count,
+             sizeof(char16_t) * (fLength - index - count));
+diff --git a/test/intltest/formatted_string_builder_test.cpp b/test/intltest/formatted_string_builder_test.cpp
+index 45721a320ac..57294e24856 100644
+--- a/test/intltest/formatted_string_builder_test.cpp
++++ b/test/intltest/formatted_string_builder_test.cpp
+@@ -22,6 +22,7 @@ class FormattedStringBuilderTest : public IntlTest {
+     void testFields();
+     void testUnlimitedCapacity();
+     void testCodePoints();
++    void testInsertOverflow();
+ 
+     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
+ 
+@@ -50,6 +51,7 @@ void FormattedStringBuilderTest::runIndexedTest(int32_t index, UBool exec, const
+         TESTCASE_AUTO(testFields);
+         TESTCASE_AUTO(testUnlimitedCapacity);
+         TESTCASE_AUTO(testCodePoints);
++        TESTCASE_AUTO(testInsertOverflow);
+     TESTCASE_AUTO_END;
+ }
+ 
+@@ -308,6 +310,45 @@ void FormattedStringBuilderTest::testCodePoints() {
+     assertEquals("Code point count is 2", 2, nsb.codePointCount());
+ }
+ 
++void FormattedStringBuilderTest::testInsertOverflow() {
++    if (quick) return;
++    // Setup the test fixture in sb, sb2, ustr.
++    UErrorCode status = U_ZERO_ERROR;
++    FormattedStringBuilder sb;
++    int32_t data_length = INT32_MAX / 2;
++    UnicodeString ustr(data_length, u'a', data_length);
++    sb.append(ustr, kUndefinedField, status);
++    assertSuccess("Setup the first FormattedStringBuilder", status);
++
++    FormattedStringBuilder sb2;
++    sb2.append(ustr, kUndefinedField, status);
++    sb2.insert(0, ustr, 0, data_length / 2, kUndefinedField, status);
++    sb2.writeTerminator(status);
++    assertSuccess("Setup the second FormattedStringBuilder", status);
++
++    ustr = sb2.toUnicodeString();
++    // Complete setting up the test fixture in sb, sb2 and ustr.
++
++    // Test splice() of the second UnicodeString
++    sb.splice(0, 1, ustr, 1, ustr.length(),
++              kUndefinedField, status);
++    assertEquals(
++        "splice() long text should not crash but return U_INPUT_TOO_LONG_ERROR",
++        U_INPUT_TOO_LONG_ERROR, status);
++
++    // Test sb.insert() of the first FormattedStringBuilder with the second one.
++    sb.insert(0, sb2, status);
++    assertEquals(
++        "insert() long FormattedStringBuilder should not crash but return "
++        "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++
++    // Test sb.insert() of the first FormattedStringBuilder with UnicodeString.
++    sb.insert(0, ustr, 0, ustr.length(), kUndefinedField, status);
++    assertEquals(
++        "insert() long UnicodeString should not crash but return "
++        "U_INPUT_TOO_LONG_ERROR", U_INPUT_TOO_LONG_ERROR, status);
++}
++
+ void FormattedStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const FormattedStringBuilder &b) {
+     // TODO: Why won't this compile without the IntlTest:: qualifier?
+     IntlTest::assertEquals("Lengths should be the same", a.length(), b.length());

diff --git a/dev-libs/icu/icu-71.1-r1.ebuild b/dev-libs/icu/icu-71.1-r1.ebuild
new file mode 100644
index 000000000000..584c243c2e41
--- /dev/null
+++ b/dev-libs/icu/icu-71.1-r1.ebuild
@@ -0,0 +1,154 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+# Please bump with dev-libs/icu-layoutex
+
+PYTHON_COMPAT=( python3_{8..10} )
+VERIFY_SIG_OPENPGP_KEY_PATH="${BROOT}"/usr/share/openpgp-keys/icu.asc
+inherit autotools flag-o-matic multilib-minimal python-any-r1 toolchain-funcs verify-sig
+
+DESCRIPTION="International Components for Unicode"
+HOMEPAGE="https://icu.unicode.org/"
+SRC_URI="https://github.com/unicode-org/icu/releases/download/release-${PV//./-}/icu4c-${PV//./_}-src.tgz"
+SRC_URI+=" verify-sig? ( https://github.com/unicode-org/icu/releases/download/release-${PV//./-}/icu4c-${PV//./_}-src.tgz.asc )"
+S="${WORKDIR}/${PN}/source"
+
+LICENSE="BSD"
+SLOT="0/${PV}"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris ~x86-winnt"
+IUSE="debug doc examples static-libs test"
+RESTRICT="!test? ( test )"
+
+BDEPEND="${PYTHON_DEPS}
+	sys-devel/autoconf-archive
+	virtual/pkgconfig
+	doc? ( app-doc/doxygen[dot] )
+	verify-sig? ( sec-keys/openpgp-keys-icu )
+"
+
+MULTILIB_CHOST_TOOLS=(
+	/usr/bin/icu-config
+)
+
+PATCHES=(
+	"${FILESDIR}/${PN}-65.1-remove-bashisms.patch"
+	"${FILESDIR}/${PN}-64.2-darwin.patch"
+	"${FILESDIR}/${PN}-68.1-nonunicode.patch"
+	"${FILESDIR}/${P}-CVE-2022-1638.patch" # bug 843731
+)
+
+src_prepare() {
+	default
+
+	# Disable renaming as it assumes stable ABI and that consumers
+	# won't use unofficial APIs. We need this despite the configure argument.
+	sed -i \
+		-e "s/#define U_DISABLE_RENAMING 0/#define U_DISABLE_RENAMING 1/" \
+		common/unicode/uconfig.h || die
+
+	# Fix linking of icudata
+	sed -i \
+		-e "s:LDFLAGSICUDT=-nodefaultlibs -nostdlib:LDFLAGSICUDT=:" \
+		config/mh-linux || die
+
+	# Append doxygen configuration to configure
+	sed -i \
+		-e 's:icudefs.mk:icudefs.mk Doxyfile:' \
+		configure.ac || die
+
+	eautoreconf
+}
+
+src_configure() {
+	# ICU tries to append -std=c++11 without this, so as of 71.1,
+	# despite GCC 9+ using c++14 (or gnu++14) and GCC 11+ using gnu++17,
+	# we still need this.
+	append-cxxflags -std=c++14
+
+	if tc-is-cross-compiler; then
+		mkdir "${WORKDIR}"/host || die
+		pushd "${WORKDIR}"/host >/dev/null || die
+
+		CFLAGS="" CXXFLAGS="" ASFLAGS="" LDFLAGS="" \
+		CC="$(tc-getBUILD_CC)" CXX="$(tc-getBUILD_CXX)" AR="$(tc-getBUILD_AR)" \
+		RANLIB="$(tc-getBUILD_RANLIB)" LD="$(tc-getBUILD_LD)" \
+		"${S}"/configure --disable-renaming --disable-debug \
+			--disable-samples --enable-static || die
+		emake
+
+		popd >/dev/null || die
+	fi
+
+	multilib-minimal_src_configure
+}
+
+multilib_src_configure() {
+	local myeconfargs=(
+		--disable-renaming
+		--disable-samples
+		--disable-layoutex
+		$(use_enable debug)
+		$(use_enable static-libs static)
+		$(use_enable test tests)
+		$(multilib_native_use_enable examples samples)
+	)
+
+	tc-is-cross-compiler && myeconfargs+=(
+		--with-cross-build="${WORKDIR}"/host
+	)
+
+	# Work around cross-endian testing failures with LTO #757681
+	if tc-is-cross-compiler && is-flagq '-flto*' ; then
+		myeconfargs+=( --disable-strict )
+	fi
+
+	# ICU tries to use clang by default
+	tc-export CC CXX
+
+	# Make sure we configure with the same shell as we run icu-config
+	# with, or ECHO_N, ECHO_T and ECHO_C will be wrongly defined
+	export CONFIG_SHELL="${EPREFIX}/bin/sh"
+	# Probably have no /bin/sh in prefix-chain
+	[[ -x ${CONFIG_SHELL} ]] || CONFIG_SHELL="${BASH}"
+
+	ECONF_SOURCE="${S}" econf "${myeconfargs[@]}"
+}
+
+multilib_src_compile() {
+	default
+
+	if multilib_is_native_abi && use doc; then
+		doxygen -u Doxyfile || die
+		doxygen Doxyfile || die
+	fi
+}
+
+multilib_src_test() {
+	# INTLTEST_OPTS: intltest options
+	#   -e: Exhaustive testing
+	#   -l: Reporting of memory leaks
+	#   -v: Increased verbosity
+	# IOTEST_OPTS: iotest options
+	#   -e: Exhaustive testing
+	#   -v: Increased verbosity
+	# CINTLTST_OPTS: cintltst options
+	#   -e: Exhaustive testing
+	#   -v: Increased verbosity
+	emake -j1 VERBOSE="1" check
+}
+
+multilib_src_install() {
+	default
+
+	if multilib_is_native_abi && use doc; then
+		docinto html
+		dodoc -r doc/html/*
+	fi
+}
+
+multilib_src_install_all() {
+	local HTML_DOCS=( ../readme.html )
+	einstalldocs
+}


             reply	other threads:[~2022-05-18 11:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-18 11:13 Andreas Sturmlechner [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-05-16 20:43 [gentoo-commits] repo/gentoo:master commit in: dev-libs/icu/, dev-libs/icu/files/ David Seifert
2024-11-10 19:49 Sam James
2023-11-13  6:07 Sam James
2022-06-19  9:13 Andreas Sturmlechner
2019-10-15 12:04 Lars Wendler
2019-06-27 10:48 Andreas Sturmlechner
2019-04-21 11:35 Lars Wendler
2019-03-30  9:59 Andreas Sturmlechner
2018-11-09  2:11 Andreas Sturmlechner
2017-09-22  6:36 Andreas Hüttel
2017-05-26 15:50 Andreas Hüttel
2017-02-18 16:49 Andreas Hüttel
2017-01-15 21:28 Andreas Hüttel
2016-11-08 17:09 Andreas Hüttel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1652872373.3d3cad32d1310cafeeed46b374ef3120c0195ff7.asturm@gentoo \
    --to=asturm@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox