Java Hangs When Converting 2.2250738585072012e-308
Copyright © 2008-2016 Exploring Binary
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.
February 9th, 2011 at 2:37 pm
@Brian,
I’m not qualified to answer that (but hopefully one of my expert readers will chime in).
February 9th, 2011 at 5:09 pm
[…] 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 […]
February 9th, 2011 at 5:49 pm
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.
February 10th, 2011 at 1:56 am
[…] 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 […]
February 10th, 2011 at 2:46 am
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…
February 10th, 2011 at 7:34 am
@#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/
February 10th, 2011 at 9:12 am
I couldn’t to take down a Tomcat server sending header Accept-Language
Why ?
February 10th, 2011 at 12:57 pm
@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.
February 10th, 2011 at 2:48 pm
Thank you, Boa13.
February 10th, 2011 at 3:01 pm
@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.
February 10th, 2011 at 7:29 pm
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).
February 11th, 2011 at 3:51 am
@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.
February 11th, 2011 at 7:20 am
@All : Did someone tested with IBM JDK ?
February 11th, 2011 at 10:10 am
“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.
February 11th, 2011 at 10:49 am
@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.
February 11th, 2011 at 11:00 am
[…] Java Hangs When Converting 2.2250738585072012e-308 […]
February 12th, 2011 at 2:53 am
@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.
February 14th, 2011 at 6:34 am
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
February 14th, 2011 at 8:29 am
@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).
February 15th, 2011 at 10:14 am
Today, Java 6 Update 24 (1.6.0_24) has been released which includes the Fix for this vulnerability. 🙂
February 15th, 2011 at 10:36 am
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.)
February 15th, 2011 at 5:36 pm
[…] Exploring Binary Etiquetado como: bug • double • java • jvm • oracle • sun […]
February 17th, 2011 at 11:15 am
[…] Page de l’auteur de la découverte : exploring Binary […]
April 16th, 2011 at 10:21 am
does not work on 64bit
May 24th, 2011 at 4:33 pm
[…] 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 […]
June 30th, 2011 at 4:41 am
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!
June 30th, 2011 at 5:50 pm
@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).
July 17th, 2013 at 12:44 am
[…] (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 […]
February 4th, 2014 at 6:59 pm
[…] the compiler itself can have bugs (it has happened in the past) […]
May 22nd, 2014 at 9:02 am
[…] importante faille de sécurité est récemment remontée qui affecte nos applications Java tournant sur serveurs […]
May 31st, 2014 at 8:32 am
[…] Hangs When Converting 2.2250738585072012e-308, here. And Kahan said, darkly, that no one was keeping track of […]
September 3rd, 2014 at 12:10 am
[…] we had a top team of InfoSec professionals, and we were on top of security patching – contributing useful fixes back to the […]
December 26th, 2014 at 3:24 pm
[…] the famous “Java Double of Death” (see http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ for details, Oracle fixed it here […]