Java Hangs When Converting 2.2250738585072012e-308

http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/


Konstantin Preißer made an interesting discovery, after reading my article “PHP Hangs On Numeric Value 2.2250738585072011e-308”: Java — both its runtime and compiler — go into an infinite loop when converting the decimal number 2.2250738585072012e-308 to double-precision binary floating-point. This number is supposed to convert to 0x1p-1022, which is DBL_MIN; instead, Java gets stuck, oscillating between 0x1p-1022 and 0x0.fffffffffffffp-1022, the largest subnormal double-precision floating-point number.

Send a Java Program Into An Infinite Loop

Compile this program and run it; the program will hang (at least it does on a 32-bit system with the latest JRE/JDK):

class runhang {
public static void main(String[] args) {
  System.out.println("Test:");
  double d = Double.parseDouble("2.2250738585072012e-308");
  System.out.println("Value: " + d);
 }
}

Send the Java Compiler Into An Infinite Loop

Try to compile this program; the compiler will hang:

class compilehang {
public static void main(String[] args) {
  double d = 2.2250738585072012e-308;
  System.out.println("Value: " + d);
 }
}

Where’s the Problem?

For the runtime case at least, Konstantin has narrowed the problem down to the “correction loop” in FloatingDecimal.java. See his comments on my PHP bug analysis article.

Like PHP, Java gets stuck crossing the normalized/unnormalized border, but in the opposite direction: it starts with an estimate just below DBL_MIN — 0x0.fffffffffffffp-1022 — and is trying to get up to DBL_MIN. but with a twist: it starts with an estimate that is correct — DBL_MIN — and then adjusts it to 0x0.fffffffffffffp-1022. It then adjusts that back to DBL_MIN, and around it goes…

Bug Report

Konstantin reported this problem to Oracle three weeks ago, but is still waiting for a reply. (Update: as per Konstantin’s comment below, the bug has been assigned “internal review ID of 1949967, which is NOT visible on the Sun Developer Network (SDN)”.)

Update: Previous Bug Reports Describe the Same Problem

Readers found two bug reports that describe the same problem (although not in terms of the magic number 2.2250738585072012e-308): bug number 100119 from 2009, and bug number 4421494 from 2001. (But don’t bother clicking on that last one — the link is now dead, as of 2/3/11.)

Addendum

As pointed out in the comments below, equivalent forms of the number cause the problem as well; examples:

  • 0.00022250738585072012e-304 (decimal point placement)
  • 00000000002.2250738585072012e-308 (leading zeros)
  • 2.225073858507201200000e-308 (trailing zeros)
  • 2.2250738585072012e-00308 (leading zeros in the exponent)
  • 2.2250738585072012997800001e-308 (superfluous digits beyond digit 17)

Update: Discussion on the Web

Check out these links for more discussion of the bug:

Update: A Fix Was Released

On 2/8/2011, Oracle released a fix.

Dingbat

132 Responses to “Java Hangs When Converting 2.2250738585072012e-308”

  1. Konstantin Preißer Says:

    Hi,

    thanks for publishing this article! :)

    Note that the ‘correction loop’ that I was referring to, is at lines 1473 – 1599 of the linked FloatingDecimal.java (marked wtih “correctionLoop”). If these lines are removed, the function does not hang any more, but the result for other numbers is less accurate than with that correction loop.

    This could also be used as a workaround, if you need to provide a user interface from a java application where the user can enter a string which is converted to a double, and it is critical that the application must not hang (e.g. when parsing the String in a Java Servlet, which is used just like PHP for creating dynamic websites), you can copy the FloatingDecimal.java into your project (change the “package sun.misc;” line), and remove the “correction loop”.
    Then you would need to replace “Double.parseDouble(…)” with “yourPackage.FloatingDecimal.readJavaFormatString(…).doubleValue()”.

    However, I think this bug is less critical than PHP’s bug, because Java Servlets are not used as much as PHP, and because of Java’s strong type system, you would have explicitly use “Double.parseDouble()” to parse a String containg a floating point number.

  2. Luciano Fiandesio Says:

    The compiler hangs on a 64bit version as well.

    java version “1.6.0_22″
    Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
    Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)

  3. Chris Gioran Says:

    Of course, it follows that scala has the same problem. If you start up the command line interpreter (scala w/o any arguments) and ask it to evaluate the value under discussion, it will hang, hogging a CPU. I assume the same will go for compiled programs as well.

    cheers

  4. Maciej Says:

    22.250738585072012e-309

  5. Johann Fridriksson Says:

    Works on Google documents too! (Spreadsheet)

    Enter this double value into a cell (you may or may not have to force the back-end to evaluate the value by inserting something like “=+2″ into a different cell).

    The Ajax back-end hangs until it times out.

  6. Johann Fridriksson Says:

    My greater-and-less-than signs disappeared in my last comment..

    …you may or may not have to force the back-end to evaluate the value by inserting something like “=cell-with-this-double-constant+2″ into a different cell (e.g. =B2+2)…

  7. Chetan Bhat Says:

    This is an awesome find! Way to go! Waiting for news about hackers abusing this bug around the world for financial gain

  8. g0dkar Says:

    Uh… use BigDecimal instead? Double and Floats are known to be buggy and have problems with some operations (like division). BigDecimal was created to address those problems.

  9. Konstantin Preißer Says:

    Hello,
    @g0dkar:

    Float and Double are used for fast floating point arithmetics, and they are in general not buggy (except this bug here). It is just the nature of floating point numbers. You should not just use BigDecimal instead of Double, because BigDecimal is intended for use when you need to do calulations which are more accurate than Doubles.

    However BigDecimal is MUCH slower than double, because it doesn’t use floating point arithmetics, but does the calculations manually (for example, a calulation which takes 0,017 ms with doubles, took 25780,43 ms with BigDecimal).
    So you should not generally replace double with BigDecimals. As long as you don’t need a better precision than Double, you should use Double.

  10. PHP vs Java: responding to bugs | pete.bevin.me Says:

    […] turns out that the same bug happens in Java, it was reported to Oracle 3 weeks ago, and there has been no response whatsoever.  Not that Sun […]

  11. Rick Regan Says:

    @Maciej,

    Yes, equivalent forms of the number work as well:

    – 0.00022250738585072012e-304 (decimal point placement)
    – 00000000002.2250738585072012e-308 (leading zeros)
    – 2.225073858507201200000e-308 (trailing zeros)
    – 2.2250738585072012e-00308 (leading zeros in the exponent)
    – 2.2250738585072012997800001e-308 (superfluous digits beyond digit 17)

    (I added this to the article.)

  12. Cómo colgar una aplicacion de Java mediante un número decimal | gr3p Says:

    […] Vía: Exploring Binary […]

  13. Andy Till Says:

    The compilehang class also crashes eclipse :P

  14. The Biggest Java WTF | Software Passion Says:

    […] one of my co-workers send me the following link. As I couldn’t believe my eyes, I have tested it myself. WTF? package wtfjava; /**  * […]

  15. Abhishek Says:

    Quite Difficult to believe but its true.

  16. Java and Double | genius' blog Says:

    […] More information can be found at Exploring Binary. […]

  17. Steven Says:

    Can you post a link to the bug report please?

  18. Rick Regan Says:

    @Steven,

    Konstantin said that Oracle has not published the bug yet.

  19. Michael Feathers Says:

    It works in Haskell’s GHCI Version 6.10.4.

    Typing 2.2250738585072012e-308 at the REPL yields 2.2250738585072014e-308

  20. Konstantin Preißer Says:

    Hi,
    When I submitted that bug, I got following E-Mail:

    Your report has been assigned an internal review ID of 1949967, which is NOT visible on the Sun Developer Network (SDN).

    Please be aware that the large volume of reports we receive sometimes prevents us from responding individually to each message.

    If the information is determined to be a new Bug or RFE, or a duplicate of a known Bug or RFE, you will receive a followup email containing a seven digit bug number.

    But so far, I have not received another response about that report.

  21. Rick Regan Says:

    @Michael,

    2.2250738585072014e-308 is the “canonical” form of DBL_MIN, but all five of these 17 digit numbers map to DBL_MIN:

    – 2.2250738585072012e-308
    – 2.2250738585072013e-308
    – 2.2250738585072014e-308
    – 2.2250738585072015e-308
    – 2.2250738585072016e-308

    2.2250738585072014e-308 is probably chosen because it is “safely” in the middle (and round-trips to boot).

  22. Rick Regan Says:

    @Konstantin,

    Did they give you an email address you can follow-up with? If so, maybe you can send them a link to this article.

  23. Konstantin Preißer Says:

    Hi Rick,

    no, they didn’t give me any email address. Just that message about the internal review ID, and a summary of the report that I made.

  24. Marius Grigaitis Says:

    Hangs in OpenJDK implementation too.

  25. Rich W Says:

    Verified both the run-time hang and compile-time hang on Mac OS X’s Java 1.6.0_22.

  26. Matko Botincan Says:

    Seems to be passing on .NET. Tried with Visual Studio 2010 C# compiler, Debug & Release targets, .NET frameworks 2.0-4.0.

  27. Spoilerone Says:

    @Andy Till: pffffft… like you need to be a rocket scientist to crash Eclipse…

  28. Stephan Beyer Says:

    Note that runhang and compilehang work perfectly(?) in the Java 1.5.0 implementation of the GNU Compiler Collection (tested with gij/gcj 4.4.5) on a 32-bit system.

    It also works with 2.2250738585072011e-308.

    However, the output is 2.225073858507201E-308 using both numbers.

  29. BITLOG infotech hírek » A PHP és a Java közös pontja Says:

    […] ExploringBinary cikke a következő két egyszerű forráskódot tette közzé a hiba demonstrálására, az első […]

  30. Grohl Says:

    Could be a good logic bomb

  31. Eirik Says:

    I’m less than impressed but not at all surprised that Oracle doesn’t take this seriously. What, the PHP bug was fixed in 3 days, Oracle hasn’t even responded in 3 weeks! Jeez,the JVM is certainly in the right hands! I can’t wait until the first hacker creates a crawler that posts this number to forms, rest-apis and attackable surfaces all over the net, wreaking all kinds of havoc. My bet is that this will happen in the next couple of days/weeks. In my experience, lots of developers do string=>primitive conversion before they do form validation, so I believe the impact of this could potentially be huge. Even if/when Oracle eventually get around to roll out a fix that works, it will still take ages until the patch is adopted by slow moving corporations. I’m surprised I haven’t read about this in any big IT newspaper yet.

  32. Wie bringe ich die JVM zum Absturz? | Moritz Siuts Says:

    […] gestern wissen das nun wahrscheinlich ziemlich viele Leute und es ist erstaunlich einfach. Im Scala-Interpreter reicht die Eingabe […]

  33. Rick Regan Says:

    @Eirik,

    Just to set the record straight: the PHP bug wasn’t taken seriously until I publicized it. That said, they fixed it in about a day — so kudos to them.

  34. Konstantin Preißer Says:

    By the way, there is another Bug in Sun’s Java 6 (at least under Windows) which crashes the VM. Try this:

    public static void main(String[] args) {
    BufferedImage rendImg = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
    BufferedImage drawImg = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = drawImg.createGraphics();
    g.transform(new AffineTransform(1E-16, 0.0, -1.0, 1.0, 0.0, 0.0));
    g.drawImage(rendImg, -rendImg.getWidth() / 2, -rendImg.getHeight() / 2, null);
    }

    Result:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006d03ed69, pid=3652, tid=1548
    #
    # JRE version: 6.0_23-b05
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (19.0-b09 mixed mode windows-amd64 compressed oops)
    # Problematic frame:
    # C [awt.dll+0x3ed69]
    #
    # An error report file with more information is saved as:
    # C:\Java-Sachen\eclipse-workspace-Test\JVMCrash\hs_err_pid3652.log
    #
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #

    I also submitted that bug to oracle some months ago (for Java 1.6.0_22), but also didn’t get any response on this. :D

  35. witty Says:

    interestingly it seems to be possible to crash almost any server running a servlet engine by passing this value inside the http header (in Accept-Language as numeric value) see [RR: dead link removed] for a short explanation :)

  36. Konstantin Preißer Says:

    Note that for the crash code above, you need the correct imports, i.e.

    import java.awt.Graphics2D;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;

    public class MyCrashTest {
    public static void main(String[] args) {
    BufferedImage rendImg = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
    BufferedImage drawImg = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g = drawImg.createGraphics();
    g.transform(new AffineTransform(1E-16, 0.0, -1.0, 1.0, 0.0, 0.0));
    g.drawImage(rendImg, -rendImg.getWidth() / 2, -rendImg.getHeight() / 2, null);
    }
    }

  37. Adam S. Says:

    @Witty

    thats interesting but I was not able to crash tomcat using your code(tried 6.0.20 and 7.0.6) under 32 bit java jdk1.6.0_12 on Win 7 64-bit

  38. Jeff Schnitzer Says:

    This is a really, really big deal.

    Most Java web application frameworks use tools like apache BeanUtils to automatically populate typed object fields from string http parameters. Any application that populates a double or Double from a form is now susceptible to a serious denial-of-service attack. REST frameworks are probably equally vulnerable.

    It wouldn’t be hard to shut down rather large chunks of the (java-powered) internet with this. How many appservers are smart enough to terminate cpu-bound threads? Not the common ones. This will require operator intervention.

    All you’d need is a script that crawls the net looking for forms, and posts that # for every field. Yikes.

  39. mresetar Says:

    Both compile and runtime problems one can see using GroovyConsole. Not sure is this good or bad thing. At least it is consistent with Java.

  40. Konstantin Preißer Says:

    Guess what! I received following email from Oracle:

    Hi Konstantin,

    We have added this bug to our bug tracking system with the ID of: 7016457 As this may be determined that this could be an exploit, it will not appear on bugs.sun.com.

    Regards,
    Roger

  41. Roberto Nogueira Says:

    This problem was already reported at the end of 2009 but apparently was not considered critical:

    https://bugs.openjdk.java.net/show_bug.cgi?id=100119

  42. Konstantin Preißer Says:

    That seems correct.
    If you enter a Value between A:= 1*2^(-1022) – 0.5*2^(-52)*2^(-1022) and B:= 1*2^(-1022), it hangs.
    A ~= 2.225073858507201136057409796709131975934 * 10 ^ (-308);
    b ~= 2.225073858507201383090232717332404064219 * 10 ^ (-308);

    For example, System.out.println(Double.parseDouble(“2.225073858507201136057409796709131975934E-308″));
    works, but
    System.out.println(Double.parseDouble(“2.225073858507201136057409796709131975935E-308″));
    hans.

  43. Konstantin Preißer Says:

    A = 2^(-1022) – 2^(-1075)
    B = 2^(-1022)

  44. Konstantin Preißer Says:

    Hmm, although in that bug report it says, the upper boundary is 2^(-1022) (Double.MIN_NORMAL), that’s not quite correct.
    It seems the upper bound is
    B = 2^(-1022) – 2^(-1076)
    ~= 2.225073858507201259573821257020768020077 * 10 ^ (-308)

  45. Roger Says:

    Hello,

    I am Roger Lewis from the Java SE team at Oracle. We would like to thank Konstantin for reporting these bugs and the concise reports. The posting by Rick and the comments by others on this thread are also much appreciated. We have our development teams investigating these bugs.

    Thank you again,
    Roger

  46. Rick Regan Says:

    Hi Roger,

    Thanks. If you can, please keep us posted — I’ll be curious to see what the fix is.

  47. Rasmus Says:

    Rick, saying that we didn’t take it seriously until you publicized is more coincidental than systematic, I think. You reported the bug on Thursday Dec.30. The holidays and New Year’s meant fewer eyes on the bug reports and you “publicized” it on Monday Jan.3 when at least some of the core folks were just sobering up and getting back online. At that point we fixed it quickly. It was about a week from bug report to a new release.

    We also get a lot of completely bogus bug reports. It takes a while to sort through the chaff. For future reference, for any bugs that seem security-related, email security@php.net.

  48. Rick Regan Says:

    Hi Rasmus,

    Point taken about the holidays. I’m willing to believe it was just bad timing (maybe I should have been partying and not messing around with subnormal numbers :)). From my point of view though it was such a simple bug to reproduce (one line of code) that I expected at least a response to the effect of “we can/can’t reproduce this.” But like you said — and like I already acknowledged — you took care of it quickly once “more eyes” were on it.

    In any case, I’ll expect MY bug reports to be fast-tracked in the future :) .

    | BTW, have you seen my article analyzing the bug?

  49. Konstantin Preißer Says:

    Hi,

    the bug report on OpenJDK suggests to change in FloatingDecimal.java inside the ‘correction loop':
    – if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){
    + if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){

    If I change this line in the FloatingPoint.java and then try

    System.out.println(myPackage.FloatingDecimal.readJavaFormatString(“2.2250738585072012e-308″).doubleValue());

    it does not hang any more, and correctly prints “2.2250738585072014E-308″ as result. So I guess that change fixes the bug ;)

  50. Rick Regan Says:

    Konstantin,

    Good work! (And to think the fix was there waiting for over a year!)

  51. Markus Says:

    Hi,

    for the record. Same with Java for security related bugs. There is a special Emailaddres for reporting security vulnerabilities: secalert_us at oracle.com.

    Thanks,
    Markus

  52. Rasmus Says:

    Rick, I did read your analysis, yes. You spend way too much time pondering this stuff.

    As for being simple to reproduce. Personally I had to go find a 32-bit vm image before I could reproduce it, so it was more than just a 1-line test script’s worth of effort. PHP bugs also go through a couple of levels of review. An initial quick bogus filter to weed out the ridiculous or incomplete ones. Since your bug wasn’t immediately marked bogus, you passed that. Then typically a closer look by someone more experienced, in this case Pierre, who was able to reproduce it and poked Dmitry for his take on it since he knows that part of the code best. Dmitry was unfortunately away skiing somewhere in Siberia, or somewhere equally remote which slowed things down by another day. I think it was then Derick who figured out it went away with -O0 which is always a bad sign and we zeroed in on it from there. I was visiting Facebook and sat down with Scott there and we tested a couple of different fixes and we determined just marking it volatile was the safest short-term fix for now.

    So, that was the full story of the fix.

    I would be interested in seeing the equivalent story for the 2009-reported Java version of this. :)

  53. Eirik Says:

    @Roger Lewis

    Java 5 is at end of life. Will an eventual bug fix be released for this platform as well?

    While we’re waiting for the fix, feel free to play around with this little curl-invocation:

    curl -H “Accept-Language: en-us;q=2.2250738585072012e-308″ http://url

    Any Tomcat-server calling getLocale() on the request (i.e most of them, especially those with Spring) will hang the processing thread. Not sure about jetty, oc4j etc but I guess they have similar weaknesses.

  54. Segurança: Loop Infinito no Java | JornalJava Says:

    […] http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ Click here to cancel reply. Name […]

  55. Konstantin Preißer Says:

    Hello,
    @Erik

    I am using Tomcat 7.0.6 for hosting Java Servlets on my Websites, and I tried to send this HTTP request:

    GET / HTTP/1.1
    Host: myhost
    Connection: keep-alive
    Accept-Language: en-us;q=2.2250738585072012e-308

    However it doesn’t seem to have any effect. Tomcat processes the request normally and doesn’t hang. (I don’t use any getLocale() calls, may this be the reason?)

  56. Rick Regan Says:

    @Rasmus,

    Yes, I DO spend way too much time pondering this stuff. But c’mon: double rounding on underflow — how cool is that? You don’t see THAT everyday!

    Thanks for the full backstory. The only thing I’ll still say is that since it was reproducible, at least that much should have been stated in the initial bug report response (and perhaps it should have been marked as a security issue at that point?).

    In any case, it doesn’t seem any harm has come to the Web from this, and I learned a ton from writing the articles.

    Thanks for reading.

  57. Mat Mannion Says:

    Isn’t this the same bug? From 2001:

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4421494

    Priority Low. Thanks Sun…

  58. Eirik Says:

    @Konstantin
    Try calling request.getLocale() in one of your servlets. If your goal is just to check it out, you can also try it on Tomcats helloworld-servlet that is bundled in the release – it calls request.getLocale.

    The actual trouble occurs in org.apache.catalina.connector.Request.parseLocalesHeader where this code is run:

    // Extract the quality factor for this entry
    double quality = 1.0;
    int semi = entry.indexOf(“;q=”);
    if (semi >= 0) {
    try {
    quality = Double.parseDouble(entry.substring(semi + 3));
    } catch (NumberFormatException e) {
    quality = 0.0;
    }
    entry = entry.substring(0, semi);
    }

  59. Gary Fry Says:

    I added this fix to FloatingDecimal.java

    1475: int iterationCount = 100;

    1477: while (–iterationCount > 0) {

    Inserted after 1599:
    if (iterationCount == 0) {
    throw new NumberFormatException(“SPIN LOOP DETECTED – TRAPPING EXPLOIT. Value = ” + this.toString());
    }

    At least this way, you will be able to detect anyone using the exploit.

    I’m sure you can loop fewer than 100 times, but I did that just to be safe as the code in that loop is hairy.

    Obviously, you’ll need to do bad things with rt.jar and replace sun.misc.FloatingDecimal.class with this one, which is against the license agreement… so this is for information purposes only!

  60. Rick Regan Says:

    @Mat Mannion,

    Wow, it looks like the same bug to me — and that report is dated March 2001!

  61. Charles Oliver Nutter Says:

    Since this affects JRuby, I decided to find a workaround that doesn’t involve tweaking rt.jar-based classes. I blogged my solution here: http://blog.headius.com/2011/02/working-around-java-doubleparsedouble.html

    It’s not particularly elegant but it works. I essentially just use BigDecimal to parse the mantissa, and then proceed from there back to a primitive double. I believe it solves the cases in question, but I’d love to have feedback on ways to improve it (on my blog…I’m not monitoring this post for comments).

  62. Massive Java bug, don’t parse 2.2250738585072012e-308 @ sellmic.com Says:

    […] a good post on this bug here via the Java Posse Google Group, if you parse the double “2.2250738585072012e-308″ it […]

  63. Mark Says:

    Apparently already reported 10 (!) years ago:
    http://bugs.sun.com/view_bug.do?bug_id=4421494
    Even includes the bug fix mentioned by others…

  64. Gary Fry Says:

    Further to my previous post #59 – You don’t specifically need to fiddle with rt.jar.

    You can of course put FloatingDecimal in it’s own jar and run java with

    -Xbootclasspath/p:

    to prepend the new FloatingDecimal to the boot clas path.

    Either way works :-)

    Also, I’ve ran Double.parseDouble nearly a billion times with random values to parse, and the maximum iterations encountered with the set I’ve tested is 3.

    100 is definately overkill, but I’m still very nervous about reducing it to 3!

  65. The ugly bug - Programming and more … Says:

    […] and it is now sleeping in thousands of systems in the world. Everything is explained in details  here. The following line of code (yes, just a simple line) will make your JVM hang in an infinite […]

  66. Clayton Says:

    The BugId 4421494 mentioned before, was removed from the Bug Database. Probably due security and shame reasons ;-)

    Couldn’t found a cached version trough google.

  67. Rick Regan Says:

    @Clayton,

    You’re right, it’s gone. I read it yesterday, so I know it was there. Wow.

  68. D Says:

    This was the content of the bug report:

    Bug ID: 4421494
    Votes 1
    Synopsis infinite loop while parsing double literal
    Category java:classes_lang
    Reported Against 1.3 , 1.4.1
    Release Fixed
    State 5-Cause Known, bug
    Priority: 4-Low
    Related Bugs 4396272 , 4749698 , 4887667 , 6876342
    Submit Date 04-MAR-2001
    Description

    java version “1.3.0”
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
    Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

    Parsing double literals very near the exact halfway point of the cutoff for
    denormalized numbers has some problems. This cutoff can be determined as the
    average of Double.longBitsToDouble(0x0010000000000000L) and
    Double.longBitsToDouble(0x000fffffffffffffL), using the precise math of
    java.math.BigInteger. The halfway point must round up, according to IEEE 754
    round-to-nearest rules.

    With this example, the literal is larger than the lines – be sure that there are
    no line breaks in the actual number when compiling.

    Basically, appending a non-zero extension at the end of the literal
    causes java.lang.Double.parseDouble to enter an infinite loop. As javac
    uses this library call, it is impossible to compile this example:

    class Literal {
    public static void main(String[] args) {
    System.out.println(
    0.000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000022250738585
    07201136057409796709131975934819546351645648023426109724822222021076945516529523
    90813508791414915891303962110687008643869459464552765720740782062174337998814106
    32673292535522868813721490129811224514518898490572223072852551331557550159143974
    76397983411801999323962548289017107081850690630666655994938275772572015763062690
    66333264756530000924588831643303777979186961204949739037782970490505108060994073
    02629371289589500035837999672072543043602840788957717961509455167482434710307026
    09144621572289880258182545180325707018860872113128079512233426288368622321503775
    66662250398253433597456888442390026549819838548794829220689472168983109969836584
    68140228542433306603398508864458040010349339704275671864433837704860378616227717
    38545623065874679014086723327636718751
    );
    }
    }

    However, remove the final 1, and the class compiles just fine. Unfortunately,
    it gives the output of 2.225073858507201E-308, intead of the correct
    2.225073858507201E-308, meaning that it rounded down instead of up.
    (Review ID: 118067)
    ======================================================================
    xxxxx@xxxxx 2004-11-11 21:44:14 GMT

    Work Around

    Don’t use either double in question (the exact halfway point or something near
    it). Instead, use a shorter literal that is closer to the desired double
    value, rather than abusing round-to-nearest rules.
    ======================================================================

    Evaluation

    Verified problem still exists in Merlin FCS; should be fixed.

    xxxxx@xxxxx 2002-05-28

    Decomitting from Tiger, problem should still be fixed in a future release.

    xxxxx@xxxxx 2003-09-08

    Submitted On 05-MAR-2001
    eblake

    Oops – I just caught a typo in my report. The correct value
    of the halfway point should be 2.2250738585072014E-308 (I
    left out the final 4).

    Submitted On 14-JUL-2004
    nadezhin_

    The problem can be fixed by changing a line “java.lang.FloatingDecimal.java:1514″ in J2SE 1.4.2
    from:
    if ( (bigIntNBits == 1) && (bigIntExp > -expBias) ){
    to:
    if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){
    .

    PLEASE NOTE: JDK6 is formerly known as Project Mustang

  69. Donnchadh Says:

    There’s this realted one:
    http://bugs.sun.com/view_bug.do;jsessionid=25194dc266f1b860256a012b3405?bug_id=4749698
    And openJDK discussion
    https://bugs.openjdk.java.net/show_bug.cgi?id=100119

  70. Rick Regan Says:

    I found what looks like a copy a discussion of the missing bug: “Request for sponsor: 4421494 infinite loop while parsing double literal.”

    (D’s comment above — #68 — has a copy.)

  71. boa13 Says:

    Tomcat has committed changes to parseLocalesHeader() late in the night of February 1st, 2011 that fix the Accept-Language issue. The HTTP/1.1 spec says the q value should have 3 digits after the period maximum, so they implemented that.

    The fix is in the recently released Tomcat 6.0.32, in the soon-to-be-released Tomcat 7.0.7, and will be in the next 5.5.x release. It is not in Tomcat 5.5.32, which was released a mere couple of hours before the fix went in.

  72. C# and .NET don't freeze when converting 2.2250738585072012e-308 - Alex van Beek - blog community Says:

    […] just read an interesing blog post: http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/. It seems that both the Java compiler and the Java runtime freeze when trying to convert the string […]

  73. phraktle Says:

    Is there a similar problem with Float.parseFloat as well?

  74. prabhu Says:

    Hi
    It is hanging only for “2.2250738585072012e-308″, for other numbers say “2.2250738585072011e-308″ or “2.2250738585072013e-308″ and so on, working fine (not hanging)….

  75. Konstantin Preißer Says:

    Hi,
    @prabhu

    It is not only hanging for 2.2250738585072012e-308.

    It is hanging for any number between
    2^(-1022) – 2^(-1075) and
    2^(-1022) – 2^(-1076).
    For example, 2.22507385850720117e-308

  76. Rick Regan Says:

    @phraktle,

    I tried FLT_MIN (1.175494351e-38 = 2-126) and a couple of values around it but there was no problem. The code in floatValue() is a little different than doubleValue(); for one, there is no correction loop. This is probably because it has enough intermediate precision (double-precision) to compute it accurately.

  77. intelectual_tortoise Says:

    @Konstantin, @g0dkar:

    I’m with g0dkar on this one.

    Been doing Java since 1.0.2 and have yet to come up with a good reason to NOT use BigDecimal. Long ago learned to avoid doubles and floats in Java at ALL costs.

    This works:
    BigDecimal d = new BigDecimal(“2.2250738585072012e-308″);

    If your app is SO performance sensitive that you need double/float rather than BigDecimal, consider Fortran.

  78. Konstantin Preißer Says:

    Hello,
    @intelectual_tortoise
    I would agree with you that if you need to to scientifical calculations which require a much higher precision (a mantissa with more than 52 bit), you should use BigDecimal than double.

    But besides that, double can be about 1516370 % faster than BigDecimal (if you do calculations which causes a growth of the mantissa, which is normally what you’re doing). If you do not require much higher precision than double, there really is no reason to use BigDecimal instead of double. Why would you like to avoid doubles and use extremely slow BigDecimal for your calculations? (You are right that you should avoid floats, as they are very less accurate, and only use them if you need to save memory).
    Especially if you need to program algorithms that take a lot of calculations with floating point numbers, it’s not advisable to use BigDecimal instead of double.

    Note that BigDecimal also requires much more memory than double, because every time it’s value changes, a new BigDecimal object needs to be created, whereas a double always takes 8 bytes, and is hardware-implemented by the underying processor.

    Please also note that since Java 1.0.2, a lot of improvements have been made to the JVM (HotSpot), for example JIT which makes Java applications nearly as fast as C(++) or other language which compile to native code.

  79. Nick Howes Says:

    Just following up from #64 where Gary Fry suggests using bootclasspath – I’ve bundled the fixed class into a jar here, in case it’s useful to anyone.

    https://github.com/halfninja/java-6-floatingdecimal

  80. Konstantin Preißer Says:

    Hmm, it’s actually not 1516370 %, but 151649488 % (I was referring to my comment above, where I made a comparison of double and BigDecimal, where double took 0,017 ms and BigDecimal 25780,43 ms.)

  81. Tom Says:

    “compilehang” hangs on IBM JREs for AIX 5.3, both 64 bits and 32 bits (Java 6 SR6 pap6460sr6-20090925_01 and pap3260sr6-20090925_01).
    I have not tested all JREs on my system, but I guess Java5 and Java14 will fail too.

  82. intelectual_tortoise Says:

    @Konstantin
    My perspective is from mostly business-oriented applications. Any performance hit associated with BigDecimal is more than made up for by not having to mop up after float/double rounding issues.

    The mantissas are relatively small, the calculations are to fixed decimal places, etc.

    Memory’s not really an issue with modern GC: calculations are usually done in a fixed scope, objects go out of scope and are GC’ed.

    If an application domain requires so many float/double calculations with large mantissas that performance becomes an issue, it begs the question whether or not Java is the right tool.

  83. seb Says:

    @intelectual_tortoise

    I’d prefer fixing a bug than changing the language.

  84. intelectual_tortoise Says:

    @seb

    Not sure I’m following. I’m not saying change the language. Neither am I saying don’t fix the bug. I’m just stating that I can’t imagine too many reasons to use the float/double aspect of the language in the problem domains for which the language is naturally suited.

  85. LE NOMBRE MAGIQUE QUI FAIT PLANTER JAVA : 2.2250738585072012E-308 Says:

    […] de la découverte du bug, mais finalement ce n’est pas mieux pour les autres puisqu’on vient d’apprendre que Java plante en convertissant le nombre 2.2250738585072012e-308.Et le pire pour Oracle et Sun, c’est que le bug a été signalé en… 2009 mais aussi […]

  86. Java: Rounding error from Double to BigDecimal « electrobabe.at Says:

    […] Another problem with Double in Java: http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ […]

  87. AusCERT » Blog Archive » Multiple vulnerabilities Says:

    […] headers will provide protection against the DOS vulnerability. The Apache Tomcat Security Team [1] http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ – —–BEGIN PGP SIGNATURE—– Version: GnuPG v1.4.9 (MingW32) Comment: Using GnuPG with Mozilla – […]

  88. Dawid Weiss Says:

    Unless there are transitive calls to parseDouble() from other Java internal methods in rt.jar (there are, but harder to exploit directly), one can use aspectj and load-time weaving to safeguard parseDouble calls as in:

    package hotfixes;

    public aspect ParseDoubleHotFix
    {
    double around(String s):
    !within(hotfixes.**) &&
    call(double java.lang.Double.parseDouble(String)) &&
    args(s)
    {
    if (s.indexOf(“2250738585072012″) >= 0) {
    throw new IllegalArgumentException(
    “We apologize for inconvenience, but this number is temporarily not” +
    ” parseable by Oracle: ” + s);
    } else {
    return Double.parseDouble(s);
    }
    }
    }

    And then running java with: java -javaagent:…/aspectjweaver*.jar …

    Works like a charm for Tomcat, for example (before they applied the Accept-Language patch).

  89. Gary Fry Says:

    @Dawid Weiss

    A nice idea, dawid. You’re right, there are a number of Java classes which in fact do use Double.parseDouble inside the JVM. I’ve scanned the runtime source for 1.6.0_22 and found the following places which use Double.parseDouble:

    C:\jvm-bug\1.6.0_22\jdk\deploy\make\macosx\javaws\Globals.java (1 hits)
    Line 336: f.setDouble(null, Double.parseDouble(value));
    C:\jvm-bug\1.6.0_22\jdk\deploy\src\javaws\share\classes\com\sun\javaws\Globals_pre.java (1 hits)
    Line 334: f.setDouble(null, Double.parseDouble(value));
    C:\jvm-bug\1.6.0_22\jdk\hotspot\src\share\tools\LogCompilation\src\com\sun\hotspot\tools\compiler\LogParser.java (7 hits)
    Line 269: Double.parseDouble(search(atts, “stamp”)),
    Line 275: p.setEnd(Double.parseDouble(search(atts, “stamp”)));
    Line 279: compile.setStart(Double.parseDouble(search(atts, “stamp”)));
    Line 338: compile.setEnd(Double.parseDouble(search(atts, “stamp”)));
    Line 346: LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, “stamp”)), id,
    Line 353: currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, “stamp”)),
    Line 372: NMethod nm = new NMethod(Double.parseDouble(search(atts, “stamp”)),
    C:\jvm-bug\1.6.0_22\jdk\j2se\make\tools\swing-nimbus\classes\org\jdesktop\synthdesigner\synthmodel\jibxhelpers\UIPropertyMapper.java (1 hits)
    Line 105: value = Double.parseDouble(ctx.attributeText(null, VALUE_NAME, null));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\java\util\jar\pack\Histogram.java (1 hits)
    Line 729: limit = (int)( limit * Double.parseDouble(av[2]) );
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xalan\internal\xsltc\compiler\Template.java (1 hits)
    Line 217: _priority = Double.parseDouble(priority);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xalan\internal\xsltc\runtime\BasisLibrary.java (1 hits)
    Line 107: result += Double.parseDouble(dom.getStringValueX(node));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xerces\internal\impl\dv\xs\AbstractDateTimeDV.java (1 hits)
    Line 807: return Double.parseDouble(buffer.substring(start, end));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xerces\internal\impl\dv\xs\DoubleDV.java (1 hits)
    Line 83: value = Double.parseDouble(s);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xerces\internal\impl\dv\xs\DurationDV.java (1 hits)
    Line 341: return Double.parseDouble(buffer.substring(start, end));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\org\apache\xpath\internal\objects\XString.java (1 hits)
    Line 133: result = Double.parseDouble(s.toString());
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\rowset\internal\XmlReaderContentHandler.java (1 hits)
    Line 990: return Double.parseDouble(s);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\tools\internal\xjc\model\CBuiltinLeafInfo.java (1 hits)
    Line 252: return JExpr.lit(DatatypeConverterImpl._parseDouble(lexical.value));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\tools\internal\xjc\reader\dtd\bindinfo\BIUserConversion.java (1 hits)
    Line 83: add( m, new BIUserConversion( bi, parse(“”)));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\xml\internal\bind\DatatypeConverterImpl.java (4 hits)
    Line 219: public double parseDouble(String lexicalXSDDouble) {
    Line 220: return _parseDouble(lexicalXSDDouble);
    Line 223: public static double _parseDouble( CharSequence _val ) {
    Line 237: return Double.parseDouble(val);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\xml\internal\bind\v2\model\impl\RuntimeBuiltinLeafInfoImpl.java (1 hits)
    Line 692: return DatatypeConverterImpl._parseDouble(text);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\xml\internal\bind\v2\runtime\reflect\opt\TransducedAccessor_field_Double.java (1 hits)
    Line 48: ((Bean)o).f_double=DatatypeConverterImpl._parseDouble(lexical);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\com\sun\xml\internal\bind\v2\runtime\reflect\opt\TransducedAccessor_method_Double.java (1 hits)
    Line 48: ((Bean)o).set_double(DatatypeConverterImpl._parseDouble(lexical));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\lang\Double.java (1 hits)
    Line 509: public static double parseDouble(String s) throws NumberFormatException {
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\math\BigDecimal.java (1 hits)
    Line 3129: return Double.parseDouble(this.toString());
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\math\BigInteger.java (1 hits)
    Line 2765: return Double.parseDouble(this.toString());
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\text\DigitList.java (1 hits)
    Line 151: return Double.parseDouble(temp.toString());
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\util\prefs\AbstractPreferences.java (2 hits)
    Line 574: * {@link Double#parseDouble(String)}. If the attempt succeeds, the return
    Line 594: result = Double.parseDouble(value);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\util\prefs\Preferences.java (3 hits)
    Line 758: * integer as by {@link Double#parseDouble(String)}. Returns the specified
    Line 760: * is inaccessible, or if Double.parseDouble(String) would throw a
    Line 766: * with Double.parseDouble, this double is returned in preference
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\java\util\Scanner.java (6 hits)
    Line 2341: typeCache = Double.valueOf(Double.parseDouble(s));
    Line 2364: * {@link Double#parseDouble Double.parseDouble}. If the token matches
    Line 2364: * {@link Double#parseDouble Double.parseDouble}. If the token matches
    Line 2366: * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
    Line 2366: * is passed to {@link Double#parseDouble(String) Double.parseDouble} as
    Line 2387: return Double.parseDouble(processFloatToken(next(floatPattern())));
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\javax\xml\bind\DatatypeConverter.java (2 hits)
    Line 217: public static double parseDouble( String lexicalXSDDouble ) {
    Line 218: return theConverter.parseDouble( lexicalXSDDouble );
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\javax\xml\bind\DatatypeConverterImpl.java (4 hits)
    Line 191: public double parseDouble(String lexicalXSDDouble) {
    Line 192: return _parseDouble(lexicalXSDDouble);
    Line 195: public static double _parseDouble( CharSequence _val ) {
    Line 209: return Double.parseDouble(val);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\javax\xml\bind\DatatypeConverterInterface.java (1 hits)
    Line 158: public double parseDouble( String lexicalXSDDouble );
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\classes\sun\reflect\annotation\AnnotationParser.java (2 hits)
    Line 446: return parseDoubleArray(length, buf, constPool);
    Line 509: private static Object parseDoubleArray(int length,
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\demo\java2d\J2DBench\src\j2dbench\report\HTMLSeriesReporter.java (2 hits)
    Line 58: lval = Double.parseDouble((String)lhs);
    Line 64: rval = Double.parseDouble((String)rhs);
    C:\jvm-bug\1.6.0_22\jdk\j2se\src\share\demo\jfc\Java2D\java2d\demos\Transforms\Rotate.java (1 hits)
    Line 131: demo.increment = Double.parseDouble(tf1.getText().trim());

    So, in reality, your aspect doesn’t quite catch everything – there are quite a few other bits you’d need to weave around. I think fundamentally you’d be much better off prepending a patched FloatingDouble to the bootstrap classpath and you can be damn sure you’ll be protected.

  90. Roger Says:

    Roger Lewis from the Java SE team at Oracle here again.

    Oracle has released a fix for this issue through Security Alert CVE-2010-4476.  For more information see:
    http://blogs.oracle.com/security/2011/02/security_alert_for_cve-2010-44.html

    Thank you again to Konstantin and Rick and other for the report and comments,
    Roger

  91. Dawid Weiss Says:

    @Gary

  92. Dawid Weiss Says:

    @Gary

    Sure, you’re right — prepending bootclasspath is the right way to go. I just thought the AspectJ solution is an elegant approach to the problem (in fact, to be complete you’d need to catch Double.valueOf() and Method.invoke() too).

    Even so, when you do the weaving, it’s nice to see in the weaver log where all these double.parsedouble calls are (as in the Tomcat example).

  93. David Hay Says:

    @Roger

    When I try to download the critical patch (after logging in), I get a HTTP 503 error for this url:

    https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&id=1291950.1

  94. boa13 Says:

    For those who are a bit lost in the labyrinth of links at the Oracle web sites, the Java SE download page contains a prominent Security Alert paragraph, and links to the following update tool:

    http://www.oracle.com/technetwork/java/javase/fpupdater-tool-readme-305936.html

    This tool patches rt.jar and must be run against all Oracle-supported JRE and JDK.

  95. Roger Says:

    @David,

    Thank you. We are adding an additional link to our download page, outside of the Oracle Support site. The download has been on the link below since the CVE was released, we are just adding links to make it easier to get to the page:

    http://www.oracle.com/technetwork/java/javase/downloads/index.html#fpupdater

    -Roger

  96. boa13 Says:

    @Dawid Weiss: The method you wanted to safeguard was probably sun.misc.FloatingDecimal#doubleValue() which is where the error really is/was.

  97. Dan Lipofsky Says:

    I just reproduced with JRockit 1.6.0_22 on Windows.
    I also confirmed that this does not hang:
    new BigDecimal(“2.2250738585072012e-308″)

  98. Dawid Weiss Says:

    @boa13

    Oh, this would be too simple… I was talking about load-time weaving and because aspectj weaver is written in Java, FloatingDecimal is loaded way before anything else is executed at the weaver level. So you can’t weave FloatingDecimal directly (with load-time weaving).

    Also, like I said — this was just an idea for a nice and elegant solution; for production I’d prepend bootclasspath with the patched FloatingDecimal.

  99. Craig Says:

    I just confirmed the issue on this JVM:
    $ java -version
    java version “1.4.2”
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2)
    Classic VM (build 1.4.2, J2RE 1.4.2 IBM AIX build ca142ifx-20100215 (SR13 FP4) (JIT enabled: jitc))

    Notably, this version of Java is what runs WebSphere Commerce, which is what powers the ecommerce sites of some of the biggest retails in the US (if not the world), who I will not name, and hope no other commenter names. Using a few curl invocations, someone could ruins the days of quite a few fortune 500’s.

    I’m currently emailing as many of these sites as I can, and trying to reach IBM. I suggest others do the same.

  100. Brian Dunbar Says:

    I’m a system admin for an application, runs on WebLogic. WLS shipped with java 1.6.0_05, the app shipped with 1.5.0_06. It’s a pretty big deal, end-users all over the org use it 24/7, some outside vendors connect, considered one of our core applications.

    How big a deal is this bug? If it were your app would you pull out the stops to patch? Wait until a schedule maintenance period? Ignore it?

  101. Rick Regan Says:

    @Brian,

    I’m not qualified to answer that (but hopefully one of my expert readers will chime in).

  102. PHP und nun Java – Bestimmte Zahl -> Fatal Error « Kissaki Blog Says:

    […] gefunden wurde wodurch PHP abschmiert wenn eine bestimmte Zahl verwendet wird ist es jetzt auch … in Java passiert. Aber nicht ganz so schlimm, in Java tritt das ganze nur in bestimmten fällen auf. Sogar den […]

  103. Wilfred Says:

    For people complaining or wondering about the speed of Oracle’s response: read their background story at http://blogs.oracle.com/henrik/2011/02/double_trouble_-_fixing_a_java_security_issue.html
    Doesn’t sound too bad to me for a company the size of Oracle.

  104. Was für ein abgefahrener Bug Says:

    […] http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/. Und ich habe schon gedacht es ist der 1. April … Veröffentlicht in AllgemeinÄhnliche ArtikelBuchkritik "UML Distilled"JAXB 2.0 und XJC in einem Ant-Skript nutzenAdjust font size in Swing applications globalInselraus: Die Datenbank DerbyChange insets/margin of a swing button […]

  105. Pierre Says:

    Another floating point issue (that hits at a much lower value) ALSO creates infinite loops and has been explained one year ago (without anyone Slashdoting it) while it harms C#, Java or PHP as well as C/C++:

    http://gwan.ch/#infiniteloop

    Know your tools…

  106. Greg Says:

    @#103:

    The blog post said:

    In the spirit of trying to be open about how we approach the responsibilities associated with being the steward of Java, I thought it would be useful to share some of the “behind the scenes” activity involving the Security Alert that we released yesterday.

    Amusingly, in the spirit of openness, the blog post now appears to have been censored.

    Still available here though: http://www.oracle.cc/2011/02/double-trouble-how-a-java-security-issue-was-fixed/

  107. Grohl Says:

    I couldn’t to take down a Tomcat server sending header Accept-Language
    Why ?

  108. boa13 Says:

    @Brian Dunbar:

    My client, who runs one of the biggest e-commerce site in my country, has dealt with it as a major high-priority must-fix issue. They had some floating-point input fields, and were running Tomcat. They had quite a few people work on that as soon as they heard about it, and fixed it in the next 24 hours.

    Anybody on the Internet could have taken the whole site down with a few hundred poisoned requests, which is trivial to do. I believe this was a low-enough volume that this would also have been under the radar of their anti-DDoS measures.

    @Grohl:

    If no code on the server calls getLocale() on the request object, then Tomcat doesn’t die.

    Most frameworks call getLocale() as part of their i18n features. The admin webapps that ship with Tomcat call getLocale() too.

  109. Brian Dunbar Says:

    Thank you, Boa13.

  110. cgicgi Says:

    @Brian Dunbar

    I fully agree with boa13.
    Today my team spent quite a bit of time patching and double-checking (wow, that expression makes sense these days!) more than 100 servers which we run as a part of our SaaS service. Kudos to Oracle, the patch works just fine.

    I just tested (only one request per shop, will cause no harm) on three different European ecommerce sites, all major brands, running on a well known ecommerce SaaS platform. They all could be ddosed with very little effort. If you think about the potential damage caused to an ecommerce site by a mere set of some thousand requests, this is an absolute prio 1 issue.

  111. nono@example.org Says:

    Actually the HTTP specs are clear on this: there shouldn’t be more than three digits after the dot. So Tomcat is at least partly faulty too here: there’s no reason to use floating-point numbers to parse a decimal value that has at most three digits after the decimal (it’s a bit as noobish as using floating-point numbers for monetary computations).

  112. boa13 Says:

    @nono:

    You are right, and Tomcat recognized their fault as soon as they heard about the problem. They fixed their implementation the day after this blog was published.

    Releases including the fix have been made on the three Tomcat branches: Tomcat 5.5.33, Tomcat 6.0.32, and Tomcat 7.0.8 are now fine.

  113. gbt Says:

    @All : Did someone tested with IBM JDK ?

  114. Brian Dunbar Says:

    “you think about the potential damage caused to an ecommerce site by a mere set of some thousand requests, this is an absolute prio 1 issue.”

    My app isn’t an ecommerce site, but it does have hooks to vendors and partners outside my corporate net. So this should be a big deal for me, as well.

    However I’d like to have the vendor give me their .02 worth on updating the java their app uses: there must be a reason why they ship 1.5 . . .

    The vendor doesn’t seem to share my sense of urgency: still waiting for them to call me back, have attempted to escalate the ticket, getting phone tree hell.

  115. cgicgi Says:

    @gbt:
    I told a customer to patch his shop. His IT told me: We’re using IBM JDK, so nothing to do here.
    Well, I couldn’t resist but ran a http-accept-language-you-know-what-I-mean request against his shop, and it took veeeeery long to process.
    So I assume that IBM JDK is affected as well.

  116. FACT-Finder hedged against a critical Java bug | FACT-Finder blog Says:

    […] Java Hangs When Converting 2.2250738585072012e-308 […]

  117. boa13 Says:

    @gbt:

    IBM JREs are affected. See comments #81 and #99.

    @Brian Dunbar:

    All Java versions dating back to 1.3 or maybe even 1.2 are affected. You do not need to update Java: Oracle has released a tool that patches the faulty rt.jar files.

  118. ths Says:

    Hallo,

    IBM released an interim Fix today.
    The bug is marked as WebSphere-related, I got it from the WebSphere AppServer twitter channel.

    http://ibm.co/gq15Tn

  119. Rick Regan Says:

    @ths,

    The second sentence in the abstract at that link says “This problem only occurs with 2.2250738585072012e-308, which also happens to be the largest floating point number” (neither are correct).

  120. Konstantin Preißer Says:

    Today, Java 6 Update 24 (1.6.0_24) has been released which includes the Fix for this vulnerability. :)

  121. Rick Regan Says:

    Thanks Konstantin.

    It doesn’t look like the JDK 6u24 source code is available yet though (I just want to double check what the fix is.)

  122. Java entra en un loop infinito al parsear “2.2250738585072012e-308″ Says:

    […] Exploring Binary Etiquetado como: bug • double • java • jvm • oracle • sun  […]

  123. Faille de sécurité : attaque par déni de service et par injection de valeur flottante. | TOCEA Says:

    […] Page de l’auteur de la découverte : exploring Binary […]

  124. bla Says:

    does not work on 64bit

  125. Kaninchen und Schlange digital: Oracle und Adobe verharren mit Java und Flash Says:

    […] Bedarf darin sieht vielzahligen Defizite auszumerzen. Haarsträubende Angriffsvektoren wie dem Server die vom Client bevorzugte Sprache mitzuteilen lassen erahnen, wie viel Vergnügen potentielle Angreifer allein beim Ausprobieren der Lücken […]

  126. Tim Acheson Says:

    I tried this on my .NET 3.5 dev env out of curiousity. No such glitch exists in C# at run-time or compile-time:

    double d1 = Double.Parse(“2.2250738585072012e-308″);
    Console.WriteLine(“Value: ” + d1);

    double d2 = 2.2250738585072012e-308;
    Console.WriteLine(“Value: ” + d2);

    If anyone can find anything similar in .NET I’d love to play with it, I can’t find anything like this, how boring!

  127. Rick Regan Says:

    @Tim,

    The other “magic number” you can try is 2.2250738585072011e-308, which tripped up PHP (I don’t think it will trip up .NET though, since I assume it uses its own proprietary conversion algorithm).

  128. Floating-Point Determinism | Random ASCII Says:

    […] (scanf is fine, and so is the conversion to text), and troublesome values that have caused both Java and PHP to hang when converting from text to double. Great […]

  129. Even faster Java Expression Evaluator | Transylvania JUG Says:

    […] the compiler itself can have bugs (it has happened in the past) […]

  130. Revue de Presse Xebia | Blog Xebia France Says:

    […] importante faille de sécurité est récemment remontée qui affecte nos applications Java tournant sur serveurs […]

  131. Exploring Binary « Pink Iguana Says:

    […] Hangs When Converting 2.2250738585072012e-308, here. And Kahan said, darkly, that no one was keeping track of […]

  132. Andrew Mulholland's blog | Thoughts on data theft and security Says:

    […] we had a top team of InfoSec professionals, and we were on top of security patching – contributing useful fixes back to the […]

Leave a Comment

(To reduce spam, cookies must be enabled)


css.php