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

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

  1. Rick Regan Says:

    @Brian,

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

  2. 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 […]

  3. 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.

  4. 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 […]

  5. 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…

  6. 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/

  7. Grohl Says:

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

  8. 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.

  9. Brian Dunbar Says:

    Thank you, Boa13.

  10. 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.

  11. 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).

  12. 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.

  13. gbt Says:

    @All : Did someone tested with IBM JDK ?

  14. 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.

  15. 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.

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

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

  17. 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.

  18. 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

  19. 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).

  20. Konstantin Preißer Says:

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

  21. 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.)

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

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

  23. 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 […]

  24. bla Says:

    does not work on 64bit

  25. 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 […]

  26. 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!

  27. 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).

  28. 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 […]

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

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

  30. 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 […]

  31. Exploring Binary « Pink Iguana Says:

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

  32. 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 […]

  33. What is meant by “releasing code tells the hackers what to attack”? | CL-UAT Says:

    […] the famous “Java Double of Death” (see http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ for details, Oracle fixed it here […]


css.php