Bug #71221 [Csd]: Null pointer deref (segfault) in get_defined_vars via ob_start

From: Date: Sat, 26 Dec 2015 04:54:56 +0000
Subject: Bug #71221 [Csd]: Null pointer deref (segfault) in get_defined_vars via ob_start
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-198230@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71221&edit=1 ID: 71221 User updated by: hugh at allthethings dot co dot nz Reported by: hugh at allthethings dot co dot nz Summary: Null pointer deref (segfault) in get_defined_vars via ob_start Status: Closed Type: Bug Package: Reproducible crash Operating System: Linux PHP Version: 7.0.1 Block user comment: N Private report: N New Comment: Thanks for the quick fix! Will there be a cve issued for this? Previous Comments: ------------------------------------------------------------------------ [2015-12-26 04:33:09] laruence@php.net Automatic comment on behalf of laruence@gmail.com Revision: http://git.php.net/?p=php-src.git;a=commit;h=6700be67f58611d08bbacc44f327ce98ed0473c9 Log: Fixed bug #71221 (Null pointer deref (segfault) in get_defined_vars via ob_start) ------------------------------------------------------------------------ [2015-12-25 20:14:28] hugh at allthethings dot co dot nz Description: ------------ Description: ------------ Found this using afl-fuzz, see http://lcamtuf.coredump.cx/afl/ Affects 7.0.0, 7.0.1, 7.0.2, but none of the 5.6 series or before. To reproduce, compile PHP normally, then run ./sapi/cli/php with the test script <?php ob_start( get_defined_vars ); ?> You should get a segfault. The test case is similar to bug #71220, and the cause is also similar, but in a different location. What is happening is the call to get_defined_vars actually goes to the function zif_get_defined_vars in Zend/zend_builtin_functions.c, where the symbol table created on line 1948 with zend_rebuild_symbol_table() returns null, and is then passed into zend_array_dup on line 1950, which produces the stack trace below. A patch to fix would be: diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6faa57c..754bca9 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1947,6 +1947,10 @@ ZEND_FUNCTION(get_defined_vars) { zend_array *symbol_table = zend_rebuild_symbol_table(); + if (symbol_table == NULL) { + return; + } + RETURN_ARR(zend_array_dup(symbol_table)); } /* }}} */ Test script: --------------- <?php ob_start( get_defined_vars ); ?> Expected result: ---------------- No crash Actual result: -------------- When compiled to ASAN, the following backtrace happens: $ ./php-7.0.2-asan ~/php-crash-7.0-get_defined_vars ASAN:SIGSEGV ================================================================= ==22087== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000020 (pc 0x00000137b99c sp 0x7ffedd5eae10 bp 0x7f7d43e57218 T0) AddressSanitizer can not provide additional info. #0 0x137b99b in zend_array_dup /root/php-src/Zend/zend_hash.c:1780 #1 0x13adf6f in zif_get_defined_vars /root/php-src/Zend/zend_builtin_functions.c:1950 #2 0x11e8793 in zend_call_function /root/php-src/Zend/zend_execute_API.c:881 #3 0x12f28ba in zend_fcall_info_call /root/php-src/Zend/zend_API.c:3574 #4 0xf5f746 in php_output_handler_op /root/php-src/main/output.c:960 #5 0xf5f746 in php_output_stack_pop /root/php-src/main/output.c:1221 #6 0xf5f746 in php_output_end_all /root/php-src/main/output.c:341 #7 0xeb5014 in php_request_shutdown /root/php-src/main/main.c:1777 #8 0x19bd1a2 in do_cli /root/php-src/sapi/cli/php_cli.c:1142 #9 0x472e0a in main /root/php-src/sapi/cli/php_cli.c:1345 #10 0x7f7d44508ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) #11 0x473ed1 in _start (/root/php-src/php-7.0.2-asan+0x473ed1) SUMMARY: AddressSanitizer: SEGV /root/php-src/Zend/zend_hash.c:1780 zend_array_dup ==22087== ABORTING Aborted When compiled without ASAN, it Segmentation Fault's, and running under gdb gives this: $ gdb -ex r -ex 'x/i $rip' -ex bt -ex c -ex quit --args ./php-7.0.2-noasan ~/php-crash-7.0-get_defined_vars <snip> Starting program: /root/php-src/php-7.0.2-noasan /root/php-crash-7.0-get_defined_vars Program received signal SIGSEGV, Segmentation fault. zend_array_dup (source=0x0) at /root/php-src/Zend/zend_hash.c:1780 warning: Source file is more recent than executable. 1780 target->nTableSize = source->nTableSize; => 0xe5ea9a <zend_array_dup+90>: mov 0x20(%rbp),%r12d #0 zend_array_dup (source=0x0) at /root/php-src/Zend/zend_hash.c:1780 #1 0x0000000000e8debd in zif_get_defined_vars (execute_data=<optimized out>, return_value=0x7fffffffd230) at /root/php-src/Zend/zend_builtin_functions.c:1950 #2 0x0000000000d568b3 in zend_call_function (fci=fci@entry=0x7ffff7072000, fci_cache=fci_cache@entry=0x7ffff7072048) at /root/php-src/Zend/zend_execute_API.c:879 #3 0x0000000000e071bb in zend_fcall_info_call (fci=0x7ffff7072000, fcc=0x7ffff7072048, retval_ptr=retval_ptr@entry=0x7fffffffd230, args=args@entry=0x0) at /root/php-src/Zend/zend_API.c:3574 #4 0x0000000000bbda34 in php_output_handler_op (context=0x7fffffffd260, handler=0x7ffff707f050) at /root/php-src/main/output.c:960 #5 php_output_stack_pop (flags=1) at /root/php-src/main/output.c:1221 #6 php_output_end_all () at /root/php-src/main/output.c:341 #7 0x0000000000b47335 in php_request_shutdown (dummy=dummy@entry=0x0) at /root/php-src/main/main.c:1777 #8 0x00000000011bdb9b in do_cli (argc=2, argv=0x18e38b0) at /root/php-src/sapi/cli/php_cli.c:1142 #9 0x00000000004473b9 in main (argc=2, argv=0x18e38b0) at /root/php-src/sapi/cli/php_cli.c:1345 Continuing. Program terminated with signal SIGSEGV, Segmentation fault. The program no longer exists. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=71221&edit=1

« previous php.bugs (#198230) next »