Bug #74540 [Opn->Nab]: use-after-free bug

From: Date: Fri, 23 Jun 2017 15:47:39 +0000
Subject: Bug #74540 [Opn->Nab]: use-after-free bug
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209658@lists.php.net to get a copy of this message
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)

« previous php.bugs (#209658) next »