Bug #74540 [Opn->Nab]: use-after-free bug
Edit report at https://bugs.php.net/bug.php?id=74540&edit=1
ID: 74540
Updated by: nikic@php.net
Reported by: yanhuacs at gmail dot com
Summary: use-after-free bug
-Status: Open
+Status: Not a bug
Type: Bug
Package: opcache
Operating System: Ubuntu14.04
PHP Version: 5.6.30
Block user comment: N
Private report: N
New Comment:
Closing as not a bug, as this is essentially the same as bug #74539, but for PHP 5.6 and the same
comments apply.
Previous Comments:
------------------------------------------------------------------------
[2017-05-04 07:49:11] yanhuacs at gmail dot com
Description:
------------
I'd like to report potential a use-after-free bug in PHP-5.6.30 as follows.
Step 1, in ext/opcache/zend_persist.c,
function zend_ast *zend_persist_ast calls function _zend_shared_memdup in line 153.
Step 2, in ext/opcache/zend_shared_alloc.c,
function _zend_shared_memdup frees "source", which is a pointer aliased with
"ast" (due to parameter passing) in line 153 in ext/opcache/zend_persist.c.
Step 3, _zend_shared_memdup returns to its call site in line 153 in ext/opcache/zend_persist.c.
Step 4, in line 154, "ast" is dereferenced, which is a use-after-free.
/*--- ext/opcache/zend_persist.c ---*/
143 static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC)
144 {
145 int i;
146 zend_ast *node;
147
148 if (ast->kind == ZEND_CONST) {
149 node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zval));
150 node->u.val = (zval*)(node + 1);
151 zend_persist_zval(node->u.val TSRMLS_CC);
152 } else {
153 node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zend_ast*) *
(ast->children - 1));
154 for (i = 0; i < ast->children; i++) {
155 if ((&node->u.child)[i]) {
156 (&node->u.child)[i] =
zend_persist_ast((&node->u.child)[i] TSRMLS_CC);
157 }
158 }
159 }
160 efree(ast);
161 return node;
162 }
/*--- ext/opcache/zend_shared_alloc.c ---*/
338 void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source TSRMLS_DC)
339 {
340 void **old_p, *retval;
341
342 if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) ==
SUCCESS) {
343 /* we already duplicated this pointer */
344 return *old_p;
345 }
346 retval = ZCG(mem);;
347 ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
348 memcpy(retval, source, size);
349 zend_shared_alloc_register_xlat_entry(source, retval);
350 if (free_source) {
351 interned_efree((char*)source);
352 }
353 return retval;
354 }
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74540&edit=1
Thread (2 messages)