Skip to content

Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed. #10085

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Changochen opened this issue Dec 12, 2022 · 5 comments

Comments

@Changochen
Copy link

Changochen commented Dec 12, 2022

Description

The following code:

<?[$i]=$i[]=$i=&$Yhh;$i[$m==$i[]=$i];$h=$i[$m==$i[]=0]+=$Yhh;

Resulted in this output:

Zend/zend_hash.c:1007: zval *_zend_hash_index_add_or_update_i(HashTable *, zend_ulong, zval *, uint32_t): Assertion `(zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed.

Reproduce steps:

./configure --disable-all --enable-address-sanitizer --disable-phpdbg --disable-cgi --with-pic --enable-debug-assertions
make -j
./sapi/cli/php -f poc.php

Git commit: b96b88b

PS: Without the debug assertions, the poc doesn't trigger a crash or abort by sanitizer.

PHP Version

PHP 8.3.0-dev

Operating System

Ubuntu 20.04

@cmb69
Copy link
Member

cmb69 commented Dec 12, 2022

I can confirm this (happens at least with PHP-8.1); I'm not sure, though, whether that's worth fixing, since the code is pathologic.

@Changochen
Copy link
Author

Changochen commented Dec 12, 2022

Running git bitsect and found the first bad commit was edc7c8c. By checking the commit message, maybe this can be also triggerred by normal code? The PoC is found by fuzzing so the code is mal-formed.

@nielsdos
Copy link
Member

I played with it a bit and found a slightly easier reproducer:

<?php
$i = &$new_array;
$i[] = $i;
$i[] = $i;
$i[] = 0;
$i[true] += $new_array; // I can only reproduce it with the key true here

@cmb69
Copy link
Member

cmb69 commented Dec 13, 2022

$i[true] += $new_array; // I can only reproduce it with the key true here

$i[1] exhibits the same behavior (expectedly).

iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Mar 29, 2023
result may be a slot in op2. In that case SEPARATE_ARRAY() will change both
result and the slot in op2. Looping over op2 and inserting the element results
in both reference-less recursion which we don't allow, and increasing the
refcount to 2, failing any further insertions into the array.

Avoid this by copying result into a temporary zval and performing separation
there instead.

Fixes phpGH-10085
@iluuu1994
Copy link
Member

See #10975 (comment). I had to revert this change. Maybe we can find a different solution.

@iluuu1994 iluuu1994 reopened this May 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants