# HG changeset patch # User Andrew John Hughes # Date 1297254965 0 # Node ID 04cd613daca901248fd6331871074de07fe38272 # Parent 6e111db7700cf9260b2c8782298cfdcbb44e01f3 S4421494, CVE-2010-4476: infinite loop while parsing double literal. 2011-02-09 Andrew John Hughes * Makefile.am: Add patch. * NEWS: Updated. * patches/security/20110209/4421494.patch: Add floating point bug fix. diff -r 6e111db7700c -r 04cd613daca9 ChangeLog --- a/ChangeLog Tue Feb 01 18:15:36 2011 +0000 +++ b/ChangeLog Wed Feb 09 12:36:05 2011 +0000 @@ -1,3 +1,10 @@ +2011-02-09 Andrew John Hughes + + * Makefile.am: Add patch. + * NEWS: Updated. + * patches/security/20110209/4421494.patch: + Add floating point bug fix. + 2011-02-01 Andrew John Hughes * NEWS: Update for 1.8.6. diff -r 6e111db7700c -r 04cd613daca9 Makefile.am --- a/Makefile.am Tue Feb 01 18:15:36 2011 +0000 +++ b/Makefile.am Wed Feb 09 12:36:05 2011 +0000 @@ -251,7 +251,8 @@ patches/security/20101012/6961084.patch \ patches/security/20101012/6963285.patch \ patches/security/20101012/6981426.patch \ - patches/security/20101012/6990437.patch + patches/security/20101012/6990437.patch \ + patches/security/20110209/4421494.patch ICEDTEA_PATCHES = \ $(SECURITY_PATCHES) \ diff -r 6e111db7700c -r 04cd613daca9 NEWS --- a/NEWS Tue Feb 01 18:15:36 2011 +0000 +++ b/NEWS Wed Feb 09 12:36:05 2011 +0000 @@ -10,6 +10,9 @@ New in release 1.8.6 (20XX-XX-XX): +* Security updates + - S4421494, CVE-2010-4476: infinite loop while parsing double literal. + New in release 1.8.5 (2011-02-01): * Security updates diff -r 6e111db7700c -r 04cd613daca9 patches/security/20110209/4421494.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/security/20110209/4421494.patch Wed Feb 09 12:36:05 2011 +0000 @@ -0,0 +1,106 @@ +# HG changeset patch +# User alanb +# Date 1297019854 0 +# Node ID d00080320e439c339594d380f0322c865553a046 +# Parent f7afe7a5e086a6af1f23dd6304bcbe7fb2b6226a +4421494: infinite loop while parsing double literal +Reviewed-by: darcy, alanb +Contributed-by: dmitry.nadezhin@oracle.com + +diff --git a/src/share/classes/sun/misc/FloatingDecimal.java b/src/share/classes/sun/misc/FloatingDecimal.java +--- openjdk/jdk/src/share/classes/sun/misc/FloatingDecimal.java ++++ openjdk/jdk/src/share/classes/sun/misc/FloatingDecimal.java +@@ -1547,7 +1547,7 @@ public class FloatingDecimal{ + if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){ + overvalue = true; // our candidate is too big. + diff = bigB.sub( bigD ); +- if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){ ++ if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){ + // candidate is a normalized exact power of 2 and + // is too big. We will be subtracting. + // For our purposes, ulp is the ulp of the +diff --git a/test/java/lang/Double/ParseDouble.java b/test/java/lang/Double/ParseDouble.java +--- openjdk/jdk/test/java/lang/Double/ParseDouble.java ++++ openjdk/jdk/test/java/lang/Double/ParseDouble.java +@@ -23,11 +23,12 @@ + + /* + * @test +- * @bug 4160406 4705734 4707389 4826774 4895911 ++ * @bug 4160406 4705734 4707389 4826774 4895911 4421494 + * @summary Test for Double.parseDouble method and acceptance regex + */ + + import java.util.regex.*; ++import java.math.BigDecimal; + + public class ParseDouble { + +@@ -416,7 +417,15 @@ public class ParseDouble { + + "0x00100p1", + "0x00.100p1", +- "0x001.100p1" ++ "0x001.100p1", ++ ++ // Limits ++ ++ "1.7976931348623157E308", // Double.MAX_VALUE ++ "4.9e-324", // Double.MIN_VALUE ++ "2.2250738585072014e-308", // Double.MIN_NORMAL ++ ++ "2.2250738585072012e-308", // near Double.MIN_NORMAL + }; + + static String paddedBadStrings[]; +@@ -546,6 +555,42 @@ public class ParseDouble { + + } + ++ /** ++ * For each subnormal power of two, test at boundaries of ++ * region that should convert to that value. ++ */ ++ private static void testSubnormalPowers() { ++ BigDecimal TWO = BigDecimal.valueOf(2); ++ // An ulp is the same for all subnormal values ++ BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE); ++ ++ System.out.println("Testing subnormal powers of two."); ++ for(int i = -1074; i <= -1022; i++) { ++ double d = Math.scalb(1.0, i); ++ ++ /* ++ * The region [d - ulp/2, d + ulp/2] should round to d. ++ */ ++ BigDecimal d_BD = new BigDecimal(d); ++ ++ BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO)); ++ BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO)); ++ ++ double convertedLowerBound = Double.parseDouble(lowerBound.toString()); ++ double convertedUpperBound = Double.parseDouble(upperBound.toString()); ++ ++ if (convertedLowerBound != d) { ++ System.out.printf("Exponent %d, unexpected lower bound converted to %a, not %a.%n", ++ i, convertedLowerBound, d); ++ } ++ ++ if (convertedUpperBound != d) { ++ System.out.printf("Exponent %d, unexpected upper bound converted to %a, not %a.%n", ++ i, convertedUpperBound, d); ++ } ++ } ++ } ++ + public static void main(String[] args) throws Exception { + rudimentaryTest(); + +@@ -558,5 +603,7 @@ public class ParseDouble { + testRegex(paddedGoodStrings, false); + testRegex(badStrings, true); + testRegex(paddedBadStrings, true); ++ ++ testSubnormalPowers(); + } + }