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 (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.2.6 OS: Solaris 10
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: basant dot kukreja at sun dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 13:01:29 2024 UTC