php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74540 use-after-free bug
Submitted: 2017-05-04 07:49 UTC Modified: 2017-06-23 15:47 UTC
From: yanhuacs at gmail dot com Assigned:
Status: Not a bug Package: opcache
PHP Version: 5.6.30 OS: Ubuntu14.04
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: yanhuacs at gmail dot com
New email:
PHP Version: OS:

 

 [2017-05-04 07:49 UTC] 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 }



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-06-23 15:47 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2017-06-23 15:47 UTC] nikic@php.net
Closing as not a bug, as this is essentially the same as bug #74539, but for PHP 5.6 and the same comments apply.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 11:01:30 2024 UTC