php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58120 my_copy_zval_ptr does not check for my_copy_zval result being NULL
Submitted: 2008-03-26 07:10 UTC Modified: 2008-03-28 16:18 UTC
From: davidf at sjsoft dot com Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.1.6 OS: Fedora Core 6
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: davidf at sjsoft dot com
New email:
PHP Version: OS:

 

 [2008-03-26 07:10 UTC] davidf at sjsoft dot com
Description:
------------
In apc_compile.c, my_copy_zval_ptr calls my_copy_zval to get a value dst_new. This is then compared to *dst and if it is different, *dst is deallocated and adjusted to point to dst_new.

The problem is that my_copy_zval can return NULL, in which case *dst is changed to NULL, and the setting of the refcount than segfaults.

(Note: this was originally detected using APC 3.0.16, but on inspection of the code the same problem is present in 3.0.17)

GDB backtrace:
Program terminated with signal 11, Segmentation fault.
#0  my_copy_zval_ptr (dst=0x2aaabed7a990, src=0x555557566a90, allocate=<value optimized out>, deallocate=0x2aaab8672280 <apc_sma_free>)
    at /usr/src/debug/APC-3.0.16/apc_compile.c:265
265         (*dst)->refcount = (*src)->refcount;

(full backtrace under Actual Results)

Variables using gdb coredump:
# this shows that dst was NULL on initial entry
local_dst_alloc = 1
dst_new = (zval *) 0x0
*src = (const zval *) 0x555557566a38
*dst = (zval *) 0x0
# 9 == IS_CONSTANT_ARRAY
(*src)->type = 9 '\t'
(*src)->value.ht = (HashTable *) 0x555557b75ae8

So for this case my_copy_zval returns NULL by using the CHEC K macro - if my_copy_hashtable returns NULL, so will my_copy_zval, and then the segfault will occur.


Reproduce code:
---------------
# In my_copy_zval_ptr
   dst_new = my_copy_zval(*dst, *src, allocate, deallocate);
    if(dst_new != *dst) {
        deallocate(*dst);
        *dst = dst_new;
    }

    Z_SET_REFCOUNT_PP(dst, Z_REFCOUNT_PP(src));

# In my_copy_zval
    case IS_CONSTANT_ARRAY:

        CHECK(dst->value.ht =
            my_copy_hashtable(NULL,
                              src->value.ht,
                              (ht_copy_fun_t) my_copy_zval_ptr,
                              (ht_free_fun_t) my_free_zval_ptr,
                              1,
                              allocate, deallocate));


Expected result:
----------------
No segfault :-)

Actual result:
--------------
Segfault; full backtrace:

Thread 1 (process 6632):
#0  my_copy_zval_ptr (dst=0x2aaabed7a990, src=0x555557566a90, allocate=<value optimized out>, deallocate=0x2aaab8672280 <apc_sma_free>)
    at /usr/src/debug/APC-3.0.16/apc_compile.c:265
#1  0x00002aaab866e098 in my_copy_hashtable_ex (dst=0x2aaabed245b8, src=<value optimized out>, copy_fn=0x2aaab866f7c0 <my_copy_zval_ptr>,
    free_fn=0x2aaab866d9a0 <my_free_zval_ptr>, holds_ptrs=1, allocate=0x2aaab86720d0 <apc_sma_malloc>, deallocate=0x2aaab8672280 <apc_sma_free>,
    check_fn=0x2aaab866dc50 <my_check_copy_default_property>) at /usr/src/debug/APC-3.0.16/apc_compile.c:972
#2  0x00002aaab866e8ea in apc_copy_new_classes (op_array=0x555558486fe8, old_count=95, allocate=0x2aaab86720d0 <apc_sma_malloc>,
    deallocate=0x2aaab8672280 <apc_sma_free>) at /usr/src/debug/APC-3.0.16/apc_compile.c:752
#3  0x00002aaab86710ef in my_compile_file (h=0x7fff780b1e90, type=8) at /usr/src/debug/APC-3.0.16/apc_main.c:461
#4  0x00002aaab5f77cb9 in ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER (execute_data=0x7fff780b2340) at /usr/src/debug/php-5.1.6/Zend/zend_vm_execute.h:1924
#5  0x00002aaab5f71dfc in execute (op_array=0x55555664fd68) at /usr/src/debug/php-5.1.6/Zend/zend_vm_execute.h:92
#6  0x00002aaab5f779fa in ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER (execute_data=0x7fff780b3030) at /usr/src/debug/php-5.1.6/Zend/zend_vm_execute.h:1971
#7  0x00002aaab5f71dfc in execute (op_array=0x555557beb7c8) at /usr/src/debug/php-5.1.6/Zend/zend_vm_execute.h:92
#8  0x00002aaab5f54efe in zend_execute_scripts (type=8, retval=<value optimized out>, file_count=3) at /usr/src/debug/php-5.1.6/Zend/zend.c:1109
#9  0x00002aaab5f19f57 in php_execute_script (primary_file=0x7fff780b55a0) at /usr/src/debug/php-5.1.6/main/main.c:1738
#10 0x00002aaab5fd23d6 in php_handler (r=0x555555d87f28) at /usr/src/debug/php-5.1.6/sapi/apache2handler/sapi_apache2.c:586
#11 0x000055555557dafa in ap_run_handler (r=0x555555d87f28) at /usr/src/debug/httpd-2.2.6/server/config.c:157
#12 0x0000555555580f8c in ap_invoke_handler (r=0x555555d87f28) at /usr/src/debug/httpd-2.2.6/server/config.c:372
#13 0x000055555558bb58 in ap_process_request (r=0x555555d87f28) at /usr/src/debug/httpd-2.2.6/modules/http/http_request.c:258
#14 0x0000555555588de0 in ap_process_http_connection (c=0x555555d404d8) at /usr/src/debug/httpd-2.2.6/modules/http/http_core.c:184
#15 0x0000555555584eb2 in ap_run_process_connection (c=0x555555d404d8) at /usr/src/debug/httpd-2.2.6/server/connection.c:43
#16 0x000055555558f7cb in child_main (child_num_arg=<value optimized out>) at /usr/src/debug/httpd-2.2.6/server/mpm/prefork/prefork.c:640
#17 0x000055555558fa5a in make_child (s=0x5555557b3d30, slot=1) at /usr/src/debug/httpd-2.2.6/server/mpm/prefork/prefork.c:736
#18 0x000055555558fb10 in startup_children (number_to_start=7) at /usr/src/debug/httpd-2.2.6/server/mpm/prefork/prefork.c:754
#19 0x0000555555590648 in ap_mpm_run (_pconf=<value optimized out>, plog=<value optimized out>, s=<value optimized out>)
    at /usr/src/debug/httpd-2.2.6/server/mpm/prefork/prefork.c:975
#20 0x000055555556b08b in main (argc=1, argv=0x7fff780b5bd8) at /usr/src/debug/httpd-2.2.6/server/main.c:730

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-03-26 07:17 UTC] davidf at sjsoft dot com
Patch that should fix this here and at http://davidf.sjsoft.com/files/APC-my_copy_zval-segfault.patch

--- apc_compile.c.orig  2008-03-26 00:46:41.000000000 -0500
+++ apc_compile.c       2008-03-26 07:03:48.000000000 -0500
@@ -296,7 +296,10 @@
         if(local_dst_alloc) deallocate(dst);
         return NULL;
     }
-    dst_new = my_copy_zval(*dst, *src, allocate, deallocate);
+    if(!(dst_new = my_copy_zval(*dst, *src, allocate, deallocate))) {
+        if(local_dst_alloc) deallocate(dst);
+        return NULL;
+    }
     if(dst_new != *dst) {
         deallocate(*dst);
         *dst = dst_new;
 [2008-03-28 16:06 UTC] rasmus@php.net
Fixed in CVS, thanks.
 [2008-03-28 16:18 UTC] rasmus@php.net
(part of 3.0.18)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Jun 18 10:01:29 2024 UTC