ID:               39751
 Updated by:       [EMAIL PROTECTED]
 Reported By:      KevinJohnHoffman at gmail dot com
-Status:           Assigned
+Status:           Closed
 Bug Type:         Reproducible crash
 Operating System: Win32
 PHP Version:      5.2.0
 Assigned To:      edink
 New Comment:

Patch applied, thanks!


Previous Comments:
------------------------------------------------------------------------

[2006-12-06 11:58:59] [EMAIL PROTECTED]

Edin, could you please check this out?

------------------------------------------------------------------------

[2006-12-06 05:25:00] KevinJohnHoffman at gmail dot com

Patch has now been submitted to [EMAIL PROTECTED]

------------------------------------------------------------------------

[2006-12-06 04:46:16] KevinJohnHoffman at gmail dot com

Description:
------------
If putenv deletes an environment variable (putenv("VAR="))
after it was set previously (putenv("VAR=xxx")) then pe->previous_entry
(pe is the internal hash table entry for the environment variable) will
point to a freed memory region.

This bug is triggered on windows because pe->previous_entry is set to
point directly to the environment string (environ[...]) instead of a
*copy* of the string. The MSVCRT library will free that string when an
environment variable is deleted. Thus, pe->previous_entry can point to
a free memory region when used later.

The patch is extremely simple... pe->previous_entry should point to a
copy of the string from the environment.

putenv is used in the above pattern by the PEAR Date\TimeZone.php file
in the inDaylightTime function. 

However, this bug affects any code that follows the above pattern. It
can also be used as an attack vector to cause a denial of service
attack on Apache/PHP servers running on windows.

This is probably the same bug as #36819. A patch will be submitted
shortly.

Reproduce code:
---------------
putenv("VAR=something");
putenv("VAR=");
//The previous_value field of the hashtable entry (pe)
//for "VAR" now points to freed memory.
//Lot's of other code here that reuses this memory block
//(overwriting it with binary data) and then frees it
//will cause problems.

//Either the script exiting or doing putenv("VAR=something")
//will cause the deconstructor on the hash table entry
//to be called (php_putenv_destructor)

//The deconstructor will call putenv using pe->previous_value
//The MSVCRT putenv function will call strlen on the arg.
//If the freed memory at pe->previous_value now points to a
//data page that is no longer valid the program will crash.

Details will be submitted along with the patch. It's hard to write a
script that executes once that will cause it to crash. 

Expected result:
----------------
The code should run without crashing and without accessing freed
memory.

Actual result:
--------------
PHP or Apache crashes. This is usually a lot easier to reproduce if
running in Apache via the handler and the page is executed several
times.

minidumps are available upon request.

01f3df1c 1023baad MSVCR70D!strlen+0x30
01f3df50 00c5fcd1 MSVCR70D!putenv+0x3d
01f3e028 00a6863a php5ts_debug!php_putenv_destructor(struct
putenv_entry * pe = 0x0311bf80)+0x51
[c:\dev\sdk\php5.2-dev\source\ext\standard\basic_functions.c @ 3835]
01f3e11c 00c60eef php5ts_debug!zend_hash_del_key_or_index(struct
_hashtable * ht = 0x01d01fb4, char * arKey = 0x031033c0 "", unsigned
int nKeyLength = 3, unsigned long h = 0xb8823d3, int flag = 0)+0x19a
[c:\dev\sdk\php5.2-dev\source\zend\zend_hash.c @ 492]
01f3e27c 009d2198 php5ts_debug!zif_putenv(int ht = 1, struct
_zval_struct * return_value = 0x03103af0, struct _zval_struct **
return_value_ptr = 0x00000000, struct _zval_struct * this_ptr =
0x00000000, int return_value_used = 0, void *** tsrm_ls =
0x01ca5890)+0x40f
[c:\dev\sdk\php5.2-dev\source\ext\standard\basic_functions.c @ 4423]
01f3e40c 009dba2f php5ts_debug!zend_do_fcall_common_helper_SPEC(struct
_zend_execute_data * execute_data = 0x01f3e5e0, void *** tsrm_ls =
0x01ca5890)+0x458 [c:\dev\sdk\php5.2-dev\source\zend\zend_vm_execute.h
@ 200]
01f3e500 009d1a6d php5ts_debug!ZEND_DO_FCALL_SPEC_CONST_HANDLER(struct
_zend_execute_data * execute_data = 0x01f3e5e0, void *** tsrm_ls =
0x01ca5890)+0xbf [c:\dev\sdk\php5.2-dev\source\zend\zend_vm_execute.h @
1681]
...
01f3f7bc 0099db9f php5ts_debug!execute(struct _zend_op_array * op_array
= 0x02cc4098, void *** tsrm_ls = 0x01ca5890)+0x2dd
[c:\dev\sdk\php5.2-dev\source\zend\zend_vm_execute.h @ 92]
01f3f9a8 00aaf3f7 php5ts_debug!zend_execute_scripts(int type = 8, void
*** tsrm_ls = 0x01ca5890, struct _zval_struct ** retval = 0x00000000,
int file_count = 3, struct _zval_struct ** orig_retval_ptr_ptr =
0x00000000)+0x19f [c:\dev\sdk\php5.2-dev\source\zend\zend.c @ 1098]
01f3fc9c 007b6c10 php5ts_debug!php_execute_script(struct
_zend_file_handle * primary_file = 0x01f3fddc, void *** tsrm_ls =
0x01ca5890)+0x367 [c:\dev\sdk\php5.2-dev\source\main\main.c @ 1781]
01f3fecc 6ff0263e php5apache2_2!php_handler(struct request_rec * r =
0x01204058)+0x610
[c:\dev\sdk\php5.2-dev\source\sapi\apache2handler\sapi_apache2.c @
604]
01f3fee4 6ff02b1e libhttpd!ap_run_handler+0x4e
...


------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=39751&edit=1

Reply via email to