php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62005 Invalid memory access when incrementally assigning to a member of a null object
Submitted: 2012-05-11 16:47 UTC Modified: 2012-05-12 05:22 UTC
From: jlee+bug at imvu dot com Assigned: laruence
Status: Closed Package: Scripting Engine problem
PHP Version: master-Git-2012-05-10 (Git) OS: Ubuntu 10.04.1 LTS
Private report: No CVE-ID:
 [2012-05-11 16:47 UTC] jlee+bug at imvu dot com
Description:
------------
Valgrind reports an invalid memory access in PHP when a script incrementally assigns to a member of a null object while a user-defined error handler is in place.  This invalid access causes occasional segfaults.  It was initially observed in PHP 5.3, but it was found to still be present when run from vanilla github source as of 2012-04-30.

I have not been able to fix the bug, but here is what I've discovered so far:

During the incremental assignment, PHP replaces the variable's null value with an empty object value, while issuing a warning.  However, it seems that there is some problem with updating the references to these values.  An invalid memory access occurs during the return from the function, when the virtual machine tries to decrement the null value's reference count after it is already zero (and has been freed).  Also, the empty object value does not get its reference count decremented and therefore gets leaked.

Please see the attached test script and valgrind log.

Test script:
---------------
#!/usr/bin/php
<?
function add_points($player, $points) {
    $player->energy += $points;
}

function errorHandler($severity, $message, $filename, $line, $super_globals) { }

set_error_handler('errorHandler');
add_points(NULL, 10);


Expected result:
----------------
I expect no invalid read or write messages in valgrind's output.

Actual result:
--------------
When running under valgrind:

==8441== Memcheck, a memory error detector
==8441== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8441== Using Valgrind-3.8.0.SVN and LibVEX; rerun with -h for copyright info
==8441== Command: /home/joe/bin/php broken_assignment.php
==8441== 
==8441== Invalid read of size 4
==8441==    at 0x7FC35C: zend_leave_helper_SPEC (zend.h:391)
==8441==    by 0x8042B4: ZEND_RETURN_SPEC_CONST_HANDLER (zend_vm_execute.h:2262)
==8441==    by 0x7FB85E: execute (zend_vm_execute.h:410)
==8441==    by 0x7BE1C7: zend_execute_scripts (zend.c:1272)
==8441==    by 0x7320CB: php_execute_script (main.c:2473)
==8441==    by 0x90CD2E: do_cli (php_cli.c:988)
==8441==    by 0x90DCD3: main (php_cli.c:1361)
==8441==  Address 0x6a12120 is 16 bytes inside a block of size 32 free'd
==8441==    at 0x4C2879F: free (vg_replace_malloc.c:427)
==8441==    by 0x78842B: _efree (zend_alloc.c:2434)
==8441==    by 0x7A8448: _zval_ptr_dtor (zend_execute_API.c:439)
==8441==    by 0x7BAFE9: _zval_ptr_dtor_wrapper (zend_variables.c:180)
==8441==    by 0x7CF504: zend_hash_clean (zend_hash.c:596)
==8441==    by 0x7FC00F: zend_leave_helper_SPEC (zend_vm_execute.h:529)
==8441==    by 0x8042B4: ZEND_RETURN_SPEC_CONST_HANDLER (zend_vm_execute.h:2262)
==8441==    by 0x7FB85E: execute (zend_vm_execute.h:410)
==8441==    by 0x7BE1C7: zend_execute_scripts (zend.c:1272)
==8441==    by 0x7320CB: php_execute_script (main.c:2473)
==8441==    by 0x90CD2E: do_cli (php_cli.c:988)
==8441==    by 0x90DCD3: main (php_cli.c:1361)

[5 other invalid read/writes omitted]

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-05-12 04:05 UTC] laruence@php.net
in 5.3, I got:

Strict Standards: Creating default object from empty value in /tmp/1.php on line 3
[Sat May 12 12:05:52 2012]  Script:  '/tmp/1.php'
/home/huixinchen/opensource/php-5.3/Zend/zend_execute.c(437) :  Freeing 0x0324AE08 
(32 bytes), script=/tmp/1.php
=== Total 1 memory leaks detected ===
 [2012-05-12 04:55 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2012-05-12 04:55 UTC] laruence@php.net
I have got a fix, assign to myself.
 [2012-05-12 05:00 UTC] laruence@php.net
more serious thing is: 
<?php
function add_points($player, $points) {
    $player->energy += $points;
    var_dump($player);
}
add_points(NULL, 2);

will output:

NULL
 [2012-05-12 05:11 UTC] laruence@php.net
-Summary: Invalid memory access when incrementally assigning to a member of a null object +Summary: unexpected behavior when incrementally assigning to a member of a null object
 [2012-05-12 05:13 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3332943c9d20a8b5e09816b11f38742de0e16085
Log: Fixed Bug #62005 (unexpected behavior when incrementally assigning to a member of a null object)
 [2012-05-12 05:20 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3332943c9d20a8b5e09816b11f38742de0e16085
Log: Fixed Bug #62005 (unexpected behavior when incrementally assigning to a member of a null object)
 [2012-05-12 05:21 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3332943c9d20a8b5e09816b11f38742de0e16085
Log: Fixed Bug #62005 (unexpected behavior when incrementally assigning to a member of a null object)
 [2012-05-12 05:22 UTC] laruence@php.net
-Summary: unexpected behavior when incrementally assigning to a member of a null object +Summary: Invalid memory access when incrementally assigning to a member of a null object -Status: Assigned +Status: Closed
 [2012-05-12 05:22 UTC] laruence@php.net
This bug has been fixed in SVN.

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/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 10:02:06 2014 UTC