Bug #74539 [Opn->Nab]: use-after-free bug
Edit report at https://bugs.php.net/bug.php?id=74539&edit=1
ID: 74539
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: 7.1.5RC1
Block user comment: N
Private report: N
New Comment:
Closing this as not a bug, per the above comments.
Previous Comments:
------------------------------------------------------------------------
[2017-05-14 19:31:33] andrew dot nester dot de at gmail dot com
Agree that there is no use-after-free bug here
Here you can see that it's called with free_source=0
https://github.com/php/php-src/blob/master/ext/opcache/zend_persist.c#L34
That's why it's not double-freed
------------------------------------------------------------------------
[2017-05-09 02:50:04] laruence@php.net
I am not sure what the problem is here, zend_accel_memdup calls _zend_shared_memdup with free_source
0(false)
------------------------------------------------------------------------
[2017-05-04 07:31:45] yanhuacs at gmail dot com
Description:
------------
I'd like to report a potential double-free (a special case of use-after-free) bug as follows.
Step 1, function _zend_shared_memdup (defined in lines 349-365 in ext/opcache/zend_shared_alloc.c)
frees "source" in line 362.
Step 2, function _zend_shared_memdup returns to its call site in function zend_persist_ast (defined
in lines 247-278 in ext/opcache/zend_persist.c)
in line 253/258/267.
Step 3, "ast" is freed in line 267 (ext/opcache/zend_persist.c). Note that "ast"
and "source" are pointer aliases due to parameter passing at line 253/258/267.
Below is code snippet.
/*--- ext/opcache/zend_shared_alloc.c ---*/
349: void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source)
350: {
351: void *old_p, *retval;
352:
353: if ((old_p = zend_hash_index_find_ptr(&ZCG(xlat_table), (zend_ulong)source)) != NULL) {
354: /* we already duplicated this pointer */
355: return old_p;
356: }
357: retval = ZCG(mem);
358: ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
359: memcpy(retval, source, size);
360: zend_shared_alloc_register_xlat_entry(source, retval);
361: if (free_source) {
362: efree(source); //////FREE the first time
363: }
364: return retval;
365: }
/*--- ext/opcache/zend_persist.c ---*/
247: static zend_ast *zend_persist_ast(zend_ast *ast)
248: {
249: uint32_t i;
250: zend_ast *node;
251:
252: if (ast->kind == ZEND_AST_ZVAL) {
253: zend_ast_zval *copy = zend_accel_memdup(ast, sizeof(zend_ast_zval));
254: zend_persist_zval(©->val);
255: node = (zend_ast *) copy;
256: } else if (zend_ast_is_list(ast)) {
257: zend_ast_list *list = zend_ast_get_list(ast);
258: zend_ast_list *copy = zend_accel_memdup(ast,
259: sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
260: for (i = 0; i < list->children; i++) {
261: if (copy->child[i]) {
262: copy->child[i] = zend_persist_ast(copy->child[i]);
263: }
264: }
265: node = (zend_ast *) copy;
266: } else {
267: uint32_t children = zend_ast_get_num_children(ast);
268: node = zend_accel_memdup(ast, sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) *
children);
269: for (i = 0; i < children; i++) {
270: if (node->child[i]) {
271: node->child[i] = zend_persist_ast(node->child[i]);
272: }
273: }
274: }
275:
276: efree(ast); //////FREE AGAIN
277: return node;
278: }
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74539&edit=1
Thread (4 messages)