Bug #74539 [NEW]: use-after-free bug
From: yanhuacs at gmail dot com
Operating system: Ubuntu14.04
PHP version: 7.1.5RC1
Package: opcache
Bug Type: Bug
Bug description:use-after-free bug
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 bug report at https://bugs.php.net/bug.php?id=74539&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=74539&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=74539&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=74539&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=74539&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=74539&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=74539&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=74539&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=74539&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=74539&r=support
Expected behavior: https://bugs.php.net/fix.php?id=74539&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=74539&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=74539&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=74539&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=74539&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=74539&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=74539&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=74539&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=74539&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=74539&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=74539&r=mysqlcfg
Thread (4 messages)
- yanhuacs at gmail dot com