Fri, 02 Mar 2007


A user supplied serialized string might trigger on 64 bit systems a tight endless loop within zend_hash_init() exhausting CPU ressources.

Affected versions

Affected is PHP 4.4.4/5.2.0 and below.

Detailed information

Before PHP 4.3.11 was released it was discovered that there is a problem in the unserialize() function that could be exploited to produce a tight endless loop inside zend_hash_init() through a negative array element count stored inside the serialized string.

This was fixed by raising an error when a negative integer value was found before it was passed to the zend_hash_init() function. When such a value was passed down to that function is resulted in a shift left integer overflow that caused a tight endless loop.

A while later there were troubles with unserialize() on 64bit systems which resulted in several variables being changed from the 'int' to 'long' type. Unfortunately zend_hash_init() still works with 'int's and therefore only the lower 32 bit of the number are passed from unserialize() to zend_hash_init().

Therefore the protection against negative element counts was no longer working, because on a 64bit system a 32bit number inside a signed 'long' can still be positive.

Proof of concept, exploit or instructions to reproduce

To reproduce it just try the following PHP code on a 64bit system.

<?php unserialize("a:2147483649:{"); ?>


PHP 4.4.5 and PHP 5.2.1 already contain fixes for this vulnerability.

You should also keep in mind that the script will still be terminated after the maximum execution time. However when this time is for example set to 30 seconds and 10 requests are sent that trigger the endless loop, this will result in a 100% CPU load situation for 5 minutes.