From 20984d673e434c0a21a167d6ace423bfd62009aa Mon Sep 17 00:00:00 2001 From: Hirokazu MORIKAWA Date: Tue, 27 Mar 2018 17:05:45 +0900 Subject: [PATCH] icu: fix CVE-2017-15422 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit [lede-17.01] Maintainer: me
 Compile tested: ar71xx, mips_24kc_gcc-5.4.0_musl-1.1.16, lede-17.01 r3863-fad29d2 Run tested: NONE Description: CVE-2017-15422 : integer overflow in icu https://security-tracker.debian.org/tracker/CVE-2017-15422 Signed-off-by: Hirokazu MORIKAWA --- libs/icu/Makefile | 2 +- libs/icu/patches/CVE-2017-15422.patch | 106 ++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 libs/icu/patches/CVE-2017-15422.patch diff --git a/libs/icu/Makefile b/libs/icu/Makefile index 1635230bb5..2fb0a85593 100644 --- a/libs/icu/Makefile +++ b/libs/icu/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=icu4c PKG_VERSION:=58.2 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-58_2-src.tgz PKG_SOURCE_URL:=http://download.icu-project.org/files/$(PKG_NAME)/$(PKG_VERSION) diff --git a/libs/icu/patches/CVE-2017-15422.patch b/libs/icu/patches/CVE-2017-15422.patch new file mode 100644 index 0000000000..50e6f2587f --- /dev/null +++ b/libs/icu/patches/CVE-2017-15422.patch @@ -0,0 +1,106 @@ +Index: source/i18n/gregoimp.cpp +=================================================================== +--- source/i18n/gregoimp.cpp (revision 40653) ++++ source/i18n/gregoimp.cpp (revision 40654) +@@ -24,4 +24,9 @@ + + int32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) { ++ return (numerator >= 0) ? ++ numerator / denominator : ((numerator + 1) / denominator) - 1; ++} ++ ++int64_t ClockMath::floorDivide(int64_t numerator, int64_t denominator) { + return (numerator >= 0) ? + numerator / denominator : ((numerator + 1) / denominator) - 1; +Index: source/i18n/gregoimp.h +=================================================================== +--- source/i18n/gregoimp.h (revision 40653) ++++ source/i18n/gregoimp.h (revision 40654) +@@ -40,4 +40,15 @@ + */ + static int32_t floorDivide(int32_t numerator, int32_t denominator); ++ ++ /** ++ * Divide two integers, returning the floor of the quotient. ++ * Unlike the built-in division, this is mathematically ++ * well-behaved. E.g., -1/4 => 0 but ++ * floorDivide(-1,4) => -1. ++ * @param numerator the numerator ++ * @param denominator a divisor which must be != 0 ++ * @return the floor of the quotient ++ */ ++ static int64_t floorDivide(int64_t numerator, int64_t denominator); + + /** +Index: source/i18n/persncal.cpp +=================================================================== +--- source/i18n/persncal.cpp (revision 40653) ++++ source/i18n/persncal.cpp (revision 40654) +@@ -214,5 +214,5 @@ + + int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH; +- year = 1 + ClockMath::floorDivide(33 * daysSinceEpoch + 3, 12053); ++ year = 1 + (int32_t)ClockMath::floorDivide(33 * (int64_t)daysSinceEpoch + 3, (int64_t)12053); + + int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33); +Index: source/test/intltest/calregts.cpp +=================================================================== +--- source/test/intltest/calregts.cpp (revision 40653) ++++ source/test/intltest/calregts.cpp (revision 40654) +@@ -13,4 +13,5 @@ + #include "calregts.h" + ++#include "unicode/calendar.h" + #include "unicode/gregocal.h" + #include "unicode/simpletz.h" +@@ -91,4 +92,5 @@ + CASE(49,Test9019); + CASE(50,TestT9452); ++ CASE(51,TestPersianCalOverflow); + default: name = ""; break; + } +@@ -2946,4 +2948,34 @@ + } + } ++ ++/** ++ * @bug ticket 13454 ++ */ ++void CalendarRegressionTest::TestPersianCalOverflow(void) { ++ const char* localeID = "bs_Cyrl@calendar=persian"; ++ UErrorCode status = U_ZERO_ERROR; ++ Calendar* cal = Calendar::createInstance(Locale(localeID), status); ++ if(U_FAILURE(status)) { ++ dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID, u_errorName(status)); ++ } else { ++ int32_t maxMonth = cal->getMaximum(UCAL_MONTH); ++ int32_t maxDayOfMonth = cal->getMaximum(UCAL_DATE); ++ int32_t jd, month, dayOfMonth; ++ for (jd = 67023580; jd <= 67023584; jd++) { // year 178171, int32_t overflow if jd >= 67023582 ++ status = U_ZERO_ERROR; ++ cal->clear(); ++ cal->set(UCAL_JULIAN_DAY, jd); ++ month = cal->get(UCAL_MONTH, status); ++ dayOfMonth = cal->get(UCAL_DATE, status); ++ if ( U_FAILURE(status) ) { ++ errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s\n", localeID, jd, u_errorName(status)); ++ } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) { ++ errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d\n", ++ localeID, jd, maxMonth, month, maxDayOfMonth, dayOfMonth); ++ } ++ } ++ delete cal; ++ } ++} + + #endif /* #if !UCONFIG_NO_FORMATTING */ +Index: source/test/intltest/calregts.h +=================================================================== +--- source/test/intltest/calregts.h (revision 40653) ++++ source/test/intltest/calregts.h (revision 40654) +@@ -78,4 +78,5 @@ + void Test9019(void); + void TestT9452(void); ++ void TestPersianCalOverflow(void); + + void printdate(GregorianCalendar *cal, const char *string); -- 2.30.2