From: stas Operating system: MacOS X 10.6.6 PHP version: 5.3SVN-2011-03-16 (SVN) Package: Scripting Engine problem Bug Type: Bug Bug description:race condition in error_handler+zend_timeout
Description: ------------ Reported by Christian Holler on mailing list, the example code produces double free with following backtrace: #0 0x955d3f82 in malloc_error_break () #1 0x954e3b63 in free () #2 0x0049a4b4 in php_error_cb (type=1, error_filename=0x2422a0c "/Users/smalyshev/Desktop/crash-reports1/crashPhpErrorCbDoubleFree/min.php", error_lineno=7, format=0x628d28 "Maximum execution time of %d second%s exceeded", args=0xbfffe638 "\001") at /Users/smalyshev/php-5.3/main/main.c:910 #3 0x002de81b in soap_error_handler (error_num=1, error_filename=0x2422a0c "/Users/smalyshev/Desktop/crash-reports1/crashPhpErrorCbDoubleFree/min.php", error_lineno=7, format=0x628d28 "Maximum execution time of %d second%s exceeded", args=0xbfffe638 "\001") at /Users/smalyshev/php- 5.3/ext/soap/soap.c:2286 #4 0x00510205 in zend_error (type=1, format=0x628d28 "Maximum execution time of %d second%s exceeded") at /Users/smalyshev/php-5.3/Zend/zend.c:1020 #5 0x00503361 in zend_timeout (dummy=27) at /Users/smalyshev/php- 5.3/Zend/zend_execute_API.c:1332 #6 <signal handler called> #7 0x954e12e1 in szone_malloc_should_clear () #8 0x954e11a8 in malloc_zone_malloc () #9 0x954df278 in malloc () #10 0x954e753c in strdup () #11 0x0049a507 in php_error_cb (type=8, error_filename=0x2422a0c "/Users/smalyshev/Desktop/crash-reports1/crashPhpErrorCbDoubleFree/min.php", error_lineno=7, format=0x62b238 "Undefined variable: %s", args=0xbffff158 "? RB\002ÎQ") at /Users/smalyshev/php-5.3/main/main.c:919 The reason seems to be that when this code in php_error_cb is run: if (display) { if (PG(last_error_message)) { free(PG(last_error_message)); } if (PG(last_error_file)) { free(PG(last_error_file)); } if (!error_filename) { error_filename = "Unknown"; } PG(last_error_type) = type; PG(last_error_message) = strdup(buffer); PG(last_error_file) = strdup(error_filename); PG(last_error_lineno) = error_lineno; } The timeout happens between freeing and reassigning last_error_message or last_error_file, and thus it is freed second time when timeout is going to process the error. Test script: --------------- <?php set_time_limit(1); register_shutdown_function("plop"); function plop() { while(true) { if ($time > 2) { break; } } } plop(); -- Edit bug report at http://bugs.php.net/bug.php?id=54264&edit=1 -- Try a snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=54264&r=trysnapshot52 Try a snapshot (PHP 5.3): http://bugs.php.net/fix.php?id=54264&r=trysnapshot53 Try a snapshot (trunk): http://bugs.php.net/fix.php?id=54264&r=trysnapshottrunk Fixed in SVN: http://bugs.php.net/fix.php?id=54264&r=fixed Fixed in SVN and need be documented: http://bugs.php.net/fix.php?id=54264&r=needdocs Fixed in release: http://bugs.php.net/fix.php?id=54264&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=54264&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=54264&r=needscript Try newer version: http://bugs.php.net/fix.php?id=54264&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=54264&r=support Expected behavior: http://bugs.php.net/fix.php?id=54264&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=54264&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=54264&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=54264&r=globals PHP 4 support discontinued: http://bugs.php.net/fix.php?id=54264&r=php4 Daylight Savings: http://bugs.php.net/fix.php?id=54264&r=dst IIS Stability: http://bugs.php.net/fix.php?id=54264&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=54264&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=54264&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=54264&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=54264&r=mysqlcfg