PHP Floating Point Bug Crashes Servers
angry tapir writes "A newly unearthed bug in certain versions of the PHP scripting language could crash servers when the software is given the task of converting a large floating point number, raising the possibility that the glitch could be exploited by hackers. The bug will cause the PHP processing software to enter an infinite loop when it tries to convert the series of digits "2.2250738585072011e-308" from the string format into the floating point format. The bug only seems to affect version 5.2 and 5.3 of the language." Adds reader alphadogg: "Computer scientist Rick Regan first reported the bug on Monday, and the PHP development team issued patches the following day."
The 1 day turn around for a patch is pretty impressive. I wish some bigger companies would offer such fast patches against vulnerabilities..
Step 1: Write stuff in PHP
Step 2: ???
Step 2.9999990834239320: Profit!
imgladiusedperl
you actually havent found it ! hahaha. something like that ?
a better patch performance than this would be to actually go back in time and fix the bug before it is discovered. but then again, there would be no bug and no bugfixing would be needed. alternate timecycle breakdown ?
Read radical news here
2.2250738585072011e-308 isn't even a large number, imagine what 1 could do!
Way less than 1.
Maybe I'm missing something, but why does PHP have its own version of strtod()? It's a standard C99 function, so you'll find it in libc or equivalent in any C99-compliant platform (including Windows) and more effort has probably gone into optimising that version than the PHP version, although if you're converting from strings to floating point values anywhere performance critical then you're probably Doing It Wrong.
Did the Zend team think that there weren't enough security holes in PHP and decide to increase the attack surface?
I am TheRaven on Soylent News
Yes each time someone access it will start an infinite loop, but each PHP page has a max. processing time (usually set to around 30 seconds). So still quite a number of requests to the offending page are needed to bring the server down.
To try the bug for yourself: $a = (float) "2.2250738585072011e-308";
Sweet. PHP finally has the qualifications to enter the X86 CPU market.
2.2250738585072011e-308 is a pretty specific number, is the bug just associated with this number or are there more potential floats out there waiting to be found?
"It is a mistake to think you can solve any major problems just with potatoes." Douglas Adams
if ($input == "2.2250738585072011e-308") { return 2.2250738585072011e-308;}
I mean, for all practical purposes, it's an infinitely small number, so why shouldn't it be an infinite loop?
make imaginary.friends COUNT=100 VISIBLE=false
Am I the only one to notice that 2.2250738585072011e-308 is not very large?
Apparently, some journalists need a patch too.
My 2.2250738585072011e-308 cents.
Anyone found the equivalent of this and then felt the need to beat someone to death?
floor ( some_$_amount * some_factor + 0.5 )
I guess I'll have to keep the copy of the combo somewhere other than on my PHP server now...
Damn_registrars has no butt-hole. Damn_registrars has no use for a butt-hole.
Tired of being "normal"? Our brand of V146R4 can give you a subnormally large PEN15! Order NOW!
Are blackbird OS's written in PHP? Also fishes?
Who would win this election: Andrew Weiner vs Andrew Weiner's weiner.
And yep TFA did qualify it as the largest subnormal double-precision number. Of course the journalist probably didn't know what that meant.
Pet peeve: Profane people propagating perfunctory pedantry.
The inconsistent type system, lack of Unicode support, lack of namespaces, quirky parser, and other stupidities (== vs. ===) weren't enough, so. Is this bug inane enough to actually get people to realize that PHP bites?
~ C.
http://slashdot.org/submission/1435314/DoS-attack-found-in-PHP-thanks-to-x87-FP
Comment removed based on user account deletion
Just curious?
I'm wondering what kind of PHP software would use floating point as an input.
I'm trying to think of all the PHP stuff I run at home and at work and can't think of a single instance. (MediaWiki, Ampache, Gallery, Bugzilla).
I don't understand why the patch solves the problem....though I haven't done any serious software development for years. It looks like all they did was add the "volatile" keyword to a variable declaration.
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_2/Zend/zend_strtod.c?r1=307095&r2=307094&pathrev=307095
From:
double aadj, aadj1, adj;
To:
volatile double aadj, aadj1, adj;
But after quickly reviewing the code, I don't see why the volatile keyword fixes this problem. It doesn't appear to be multithreaded code where another thread could stomp on the variable, and it just seems to be straight arithmetic, it doesn't seem like they are handing it off to a math coprocessor and then later waiting for the variable to be set.
Does the volatile keyword change the compiler optimizations in a way that avoids the problem?
How many servers are still on 32-bit processors? I'm sure they're out there, but Opterons were 64-bit at least 7 years ago and Xeons about 6 years ago. If you've got servers older than 6 years or are running servers on commodity hardware, OK. But is this really a widespread issue? One issue could be running 32-bit VM hosts, I suppose, on hardware that doesn't have VT extensions (and thus hosts must be 32-bit).
I wonder how many of you read this article's summary and them immediately wrote a quick PHP script to perform this exact conversion. If you did, did you crash your machine or did you encounter a disappointing non-event?
- James
The i387 (and its successors) suck as floating-point hardware; this we know. However, this bug isn't as crippling as it might seem. This bug won't affect amd64 machines running in 64-bit mode where the compiler is GCC (since GCC uses SSE2 in that case). It also won't affect any Mac OS X machines, since they made the smart move to always use SSE2 on Intel hardware since all of the Intel chips they've ever shipped support it. And I think FreeBSD uses double precision mode by default, so this probably won't affect them either, unless PHP puts the libc into extended-precision mode.
That server must be 32bit then as this bug is pretty much limited to 32bit versions of php (reference: http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/)
I think some /. user did try testing this out on a variety of servers.
PHP, my days of not taking you seriously are certainly coming to a middle.
<php echo "start\n"; $a = (float) "2.2250738585072011e-308"; echo $a,"\n"; echo "end\n"; ?>
It got this: /home/dougie/public_html/test_crud/bug.php on line 3
[Thu Jan 06 23:30:49 2011] [error] [client 10.1.1.30] PHP Fatal error: Maximum execution time of 30 seconds exceeded in
Sigs. We don't need no steenking sigs.
And thread safety? It's a pure function! It doesn't need any thread safety!
strtod() has no side effects, but it still reads global variables. Does your locale use a period or a comma as a decimal point? And did another thread change the locale behind your function's back?
FORTRAN is just too damn slow for such things.
Especially when he spends most of his time riching.
mb_internal_encoding('UTF-8');
Fatal error: mb_internal_encoding is not defined because mbstring is not enabled by default. And no, you can't install this extension on your hosting company's copy of PHP.
I tried it, couldn't trigger the bug.
Of course, I'm running on 64bits systems...
I didn't test PHP, because I never use it.
I did, however, do the responsible thing and ask myself, "does code that I maintain have a similar bug, and does its test suite validate it?" I checked the Tcl test suite, and discovered that it lacked a test for the case. I added test cases for input and output conversion of the largest positive subnormal, the smallest negative subnormal, the smallest positive normal, and the largest negative normal. (All the test cases passed, so committing them ended what I had to do.)
Tcl, too, has its own conterparts to strtod and sprintf("%g"), because it depends on float->string->float being 100% lossless and on having the string representation of a float be the shortest string that reconverts to the given number. It's quite tricky to get right; this particular corner case is the tip of the iceberg.
That's my favorite number.
Why is this joke of a programming language so popular is beyond me. It's a complete failure, obviously created by a bunch of first grade students who have no clear idea about syntax and uniformity. Every new version breaks compatibility with older scripts and at the same time adds more moronisms. Ugh!
You could always change the combination to 12345. It's always worked for me.
$x = 2.2250738585072011e-308;
$x = 2.2250738585072011e-308;
$x = 2.2250738585072011e-308;
Table-ized A.I.
Maybe because the target number is slashdotted?
Table-ized A.I.