php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58283 Race condition on shared zvals
Submitted: 2008-07-22 09:47 UTC Modified: 2008-08-01 06:49 UTC
From: pr at bgagroup dot net Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.2.4 OS: Linux
Private report: No CVE-ID: None
 [2008-07-22 09:47 UTC] pr at bgagroup dot net
Description:
------------
The patch for bug #14352 triggers a race condition on shared zvals.
Since the opcodes array in my_prepare_op_array_for_execution is only copied when deep_copy flag is set, concurrent access to the same script will eventually lead to a illegal free on shared zvals in the opcodes array.

Reproduce code:
---------------
This can be reproduced using the php debug build running the following simple script <?php $a = 1; ?> and a http load testing tool, eg. siege -c100 -r100 -d0 http://localhost/script.php

Actual result:
--------------
from apache error log:
---------------------------------------
/php-5.2.6/Zend/zend_variables.c(175) : Block 0x7fab574b2390 status:
/php-5.2.6/Zend/zend_execute.h(70) : Actual location (location was relayed)
Invalid pointer: ((size=0x00000004) != (next.prev=0x00000001))
Invalid pointer: ((prev=0x100000000) != (prev.size=0x00000004))
---------------------------------------

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-07-22 09:49 UTC] pr at bgagroup dot net
The following patch always at least shallow copies the opcodes array.
Index: apc_compile.c
===================================================================
RCS file: /repository/pecl/apc/apc_compile.c,v
retrieving revision 3.108
diff -u -u -b -B -r3.108 apc_compile.c
--- apc_compile.c	17 Jul 2008 16:39:13 -0000	3.108
+++ apc_compile.c	22 Jul 2008 10:50:13 -0000
@@ -1269,8 +1269,6 @@
     FETCH_AUTOGLOBAL(_FILES);
     FETCH_AUTOGLOBAL(_REQUEST);
 
-    if(needcopy) {
-
         dst->opcodes = (zend_op*) apc_xmemcpy(src->opcodes,
                                     sizeof(zend_op) * src->last,
                                     apc_php_malloc);
@@ -1278,6 +1276,7 @@
         dzo = dst->opcodes;
         while(i > 0) {
 
+		if(needcopy) {
             if( ((zo->op1.op_type == IS_CONST &&
                   zo->op1.u.constant.type == IS_CONSTANT_ARRAY)) ||
                 ((zo->op2.op_type == IS_CONST &&
@@ -1287,6 +1286,7 @@
                     assert(0); /* emalloc failed or a bad constant array */
                 }
             }
+		}
 
             switch(zo->opcode) {
                 case ZEND_JMP:
@@ -1316,26 +1316,6 @@
             zo++;
             dzo++;
         }
-    } else {  /* !needcopy */
-        /* The fetch is only required if auto_globals_jit=1  */
-        if(do_prepare_fetch_global)
-        {
-            zo = src->opcodes;
-            while(i > 0) {
-
-                if(zo->opcode == ZEND_FETCH_R ||
-                   zo->opcode == ZEND_FETCH_W ||
-                   zo->opcode == ZEND_FETCH_IS ||
-                   zo->opcode == ZEND_FETCH_FUNC_ARG
-                  ) {
-                    APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
-                }
-
-                i--;
-                zo++;
-            }
-        }
-    }
     return 1;
 }
 /* }}} */
 [2008-08-01 06:49 UTC] gopalv82 at yahoo dot com
that crash was due to constants which had refcounts of 2/0

http://news.php.net/php.pecl.cvs/11165

should fix it.

Thanks for the awesome QA'ing
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jun 02 06:01:28 2024 UTC