php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #45751 [PATCH] Using auto_prepend_file crashes (out of scope stack address use).
Submitted: 2008-08-08 04:35 UTC Modified: 2008-08-24 08:17 UTC
From: basant dot kukreja at sun dot com Assigned: dmitry
Status: Closed Package: Scripting Engine problem
PHP Version: 5.2.6 OS: Solaris 10
Private report: No CVE-ID:
 [2008-08-08 04:35 UTC] basant dot kukreja at sun dot com
Description:
------------
Stack pointer &execute_data.opline (&EG(opline)) is used beyond the scope and hence crashes php with auto_preprend_file.

I wrote a small test plugin : test.c and then loaded the plugin into php using php.ini
extension=test.so

$ ./sapi/cli/php -d "auto_prepend_file=inc.inc" -d "include_path=/opt2/coolstackbld/svn/CoolStackDev/src/php5/php-5.2.6/tests/lang" -f /tmp/test.php
Included!
Segmentation Fault (core dumped)


Reproduce code:
---------------
Test plugin location : (skydrive) :
http://yqaghq.blu.livefilestore.com/y1phzvjT69U9PiUNjW9NjakZZ5It3VOAEhADJusnkoorLiwGfeVlK6zTz-8AprvloPplXlNkaHUYD9sS9idFWZhcg/test.c?download

Expected result:
----------------
Normal behaviour

Actual result:
--------------
php crashes

$ pstack core
core 'core' of 23827:   ./sapi/cli/php -d auto_prepend_file=inc.inc -d include_path=/opt2/cool
 003b8e4c zend_get_executed_lineno (5be8a0, 5897c, ffe39448, 55570c, ff1531c0, 57400) + 3c
 003d9f78 zend_execute_scripts (8, 0, 3, 1, 2, 5763c) + 11c
 0032d9bc php_execute_script (ffffffff, ffbff2cd, 5be3e0, ffbfefe0, 0, 5ae3a0) + 2b0
 0048e5e4 main     (10000, 5addc8, 2d, 2f, 48cac0, 1ac0) + 1ae4
 000a8f28 _start   (0, 0, 0, 0, 0, 0) + 108

 Debugger showed that it was crashing in line 394 of zend_execute_API.c :
391  ZEND_API uint zend_get_executed_lineno(TSRMLS_D)
392  {
393  	if (EG(opline_ptr)) {
394  		return active_opline->lineno;

EG(online_ptr) points to arbitrary value ( a pointer value in stack) and it
crashes in active_opline->lineno.
active_opline->lineno is *EG(opline_ptr)


We found this issue when php was crashing while dtrace plugin was loaded :
$ ./sapi/cli/php -d "auto_prepend_file=inc.inc" -d "include_path=/opt2/coolstackbld/svn/CoolStackDev/src/php5/php-5.2.6/tests/lang" -f /tmp/test.php

To simpilfy thing, I wrote my test plugin and reproduced the crash.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-08-08 04:36 UTC] basant dot kukreja at sun dot com
The issue was that we are saving stack address execute_data.opline into
EG(opline_ptr) in execute function in zend_vm_execute.h (line 74). 
	EG(opline_ptr) = &EX(opline);

After function execute is finished, EG(opline_ptr) is not reset to NULL. This
point to previously used stack. Fix is that before we return we should set
EG(opline_ptr) to NULL.

Suggested Patch  :
--- Zend/zend_vm_execute_ORIG.h	2008-08-07 18:42:47.876727000 -0700
+++ Zend/zend_vm_execute.h	2008-08-07 18:44:40.481725000 -0700
@@ -90,6 +90,7 @@
 #endif
 
 		if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) {
+			EG(opline_ptr) = NULL;
       return;
 		}
 [2008-08-08 04:39 UTC] basant dot kukreja at sun dot com
Here is the test plugin : 
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "zend_execute.h"


/* {{{ test_functions[] */
function_entry test_functions[] = {
	{NULL, NULL, NULL}
};
/* }}} */

static void (*ye_olde_execute)(zend_op_array *op_array TSRMLS_DC);

void php_test_execute(zend_op_array *op_array TSRMLS_DC)
{
	zend_get_executed_lineno(TSRMLS_C);
	ye_olde_execute(op_array TSRMLS_CC);
}


/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(test)
{
	ye_olde_execute = zend_execute;
	zend_execute = php_test_execute;
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(test)
{
	zend_execute = ye_olde_execute;
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(test)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "test support", "enabled");
	php_info_print_table_end();
}
/* }}} */

/* {{{ test_module_entry */
zend_module_entry test_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
	STANDARD_MODULE_HEADER,
#endif
	"test",
	test_functions,
	PHP_MINIT(test),
	PHP_MSHUTDOWN(test),
	NULL,
	NULL,
	PHP_MINFO(test),
	"1.0.3",
	STANDARD_MODULE_PROPERTIES
};
/* }}} */

#ifdef COMPILE_DL_TEST
ZEND_GET_MODULE(test)
#endif
 [2008-08-08 19:37 UTC] basant dot kukreja at sun dot com
Bug reproduces in latest php sources. It crashes at the same place.

[.../php5.2-200808081630] $ ./sapi/cli/php -d "auto_prepend_file=inc.inc" -d "include_path=/opt2/coolstackbld/svn/CoolStackDev/src/php5/php-5.2.6/tests/lang" -f /tmp/test.php
Included!
Segmentation Fault (core dumped)
[.../php5.2-200808081630] $ pstack core
core 'core' of 22725:   ./sapi/cli/php -d auto_prepend_file=inc.inc -d include_path=/opt2/cool
 0042e724 zend_get_executed_lineno (61a138, 57400, ff1531e8, 608590, 5778c, 1a8800) + 40
 00450234 zend_execute_scripts (8, 0, ffbfe824, 609580, 609610, 0) + 124
 003a5294 php_execute_script (ffffffff, ffbff2bd, 619c78, ffbfefd0, 0, 609be8) + 2b0
 004e6d70 main     (4e5310, 56788, 6098d0, 5880c, 609610, 1) + 1a20
 000a8f88 _start   (0, 0, 0, 0, 0, 0) + 108


php.ini :
-----------------------------

[PHP]
...
extension_dir=/opt/coolstack/php5latest/lib/php/extensions/no-debug-non-zts-20060613
; CSKmysql32 is required for mysql and mysqli extensions.
extension=test.so
...

-----------------------------
Please note that  execute data is a local variable in execute function.
execute_data.opline is a stack variable. It's address is stored
in global EG(opline_ptr). Global variable EG(opline_ptr) needs to be cleared
before the function returns.

zend_vm_execute.h
ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
{
	zend_execute_data execute_data;
...
	EG(opline_ptr) = &EX(opline);
-----------------------------
 [2008-08-18 23:58 UTC] basant dot kukreja at sun dot com
I was waiting for my suggested fix to be committed. I am able to reproduce the bug in recent sources as mentioned in Comment 3 (Aug 8th).
 [2008-08-20 06:42 UTC] jani@php.net
Dmitry, can you check this out?
 [2008-08-21 13:42 UTC] dmitry@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2008-08-24 08:17 UTC] basant dot kukreja at sun dot com
Thank you for fixing the bug.
I think you have added the line in ZEND_VM_RETURN_FROM_EXECUTE_LOOP
	EG(opline_ptr) = NULL; \


Is there any option available where I can see the exact patch for the bug? I would like to use the patch in 5.2.6.

Is there anything else needed to fix this bug?

I would appreciate any response.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 20:01:57 2014 UTC