Skip to content
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

Assertion failure ext/opcache/jit/zend_jit_ir.c:8940 #17428

Closed
YuanchengJiang opened this issue Jan 10, 2025 · 0 comments
Closed

Assertion failure ext/opcache/jit/zend_jit_ir.c:8940 #17428

YuanchengJiang opened this issue Jan 10, 2025 · 0 comments

Comments

@YuanchengJiang
Copy link

Description

The following code:

<?php
$cls = new EmptyIterator();
srand(1000);
error_reporting(E_ALL & ~E_DEPRECATED);
testConversion('', '');
testConversion("begin 0644 filename\n#0V%T\n", 'Cat');
testConversion("begin 0644 filename\n::'1T<#HO+W=W=RYW:6MI<&5D:6\$N;W)G#0H`\n", "http://www.wikipedia.org\r\n");
testConversion("begin 0644 filename\n#`0(#\n", "\x01\x02\x03");
testConversion("begin 0644 filename\n$`0(#\"@``\n", "\x01\x02\x03\n");
function testRoundTrip($data) {
die("Round-trip failed! Expected " . bin2hex($data) . " to round-trip; actually got " . bin2hex($decoded));
}
for ($iterations = 0; $iterations < 500; $iterations++) {
$strlen = rand(1, 300);
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < $strlen; $i++) {
$randstring .= $characters[rand(0, strlen($characters) - 1)];
}
testRoundTrip($randstring);
}
echo "Done!\n";
throw new Hello(new stdClass);

Resulted in this output:

php: ext/opcache/jit/zend_jit_ir.c:8940: int zend_jit_init_fcall(zend_jit_ctx *, const zend_op *, uint32_t, const zend_op_array *, zend_ssa *, const zend_ssa_op *, int, zend_jit_trace_rec *, int): Assertion `call_level > 0' failed.
Aborted (core dumped)

To reproduce:

-d "zend_extension=/home/phpfuzz/WorkSpace/flowfusion/php-src/modules/opcache.so" -d "opcache.enable_cli=1" -d "opcache.jit=1205"

PHP Version

nightly

Operating System

No response

@nielsdos nielsdos self-assigned this Jan 10, 2025
nielsdos added a commit to nielsdos/php-src that referenced this issue Jan 10, 2025
The code to update the call_level in that case skips the opline itself,
as that's handled by the tail handler, and then wants to set the opline
to the last opline of the block because the code below the switch will
update the call_level for that opline.
However, the test has a block with a single THROW, so the opline is not
correctly updated to the end opline of the block.
nielsdos added a commit to nielsdos/php-src that referenced this issue Jan 10, 2025
The code to update the call_level in that case skips the opline itself,
as that's handled by the tail handler, and then wants to set the opline
to the last opline of the block because the code below the switch will
update the call_level for that opline.
However, the test has a block with a single opline (THROW). The block
after that has ZEND_INIT_FCALL, because `i` points to ZEND_INIT_FCALL
now, it erroneously causes the call_level after the switch.
Although it suffices to change `i` to `end` (none of the opcodes here
occur in `zend_jit_dec_call_level`), I added a goto label as well to be
safer for the future in case the list of opcodes changes.
nielsdos added a commit to nielsdos/php-src that referenced this issue Jan 10, 2025
The code to update the call_level in that case skips the opline itself,
as that's handled by the tail handler, and then wants to set the opline
to the last opline of the block because the code below the switch will
update the call_level for that opline.
However, the test has a block with a single opline (THROW). The block
after that has ZEND_INIT_FCALL, because `i` points to ZEND_INIT_FCALL
now, it erroneously causes the call_level after the switch.
Although it suffices to change `i` to `end` (none of the opcodes here
occur in `zend_jit_dec_call_level`), I added a goto label as well to be
safer for the future in case the list of opcodes changes.
nielsdos added a commit to nielsdos/php-src that referenced this issue Jan 10, 2025
The code to update the call_level in that case skips the opline itself,
as that's handled by the tail handler, and then wants to set the opline
to the last opline of the block because the code below the switch will
update the call_level for that opline.
However, the test has a block with a single opline (THROW). The block
after that has ZEND_INIT_FCALL, because `i` points to ZEND_INIT_FCALL
now, it erroneously causes the call_level after the switch.
Although it suffices to change `i` to `end` (none of the opcodes here
occur in `zend_jit_dec_call_level`), I added a goto label as well to be
safer for the future in case the list of opcodes changes.
nielsdos added a commit that referenced this issue Jan 14, 2025
* PHP-8.4:
  Fix GH-17428: Assertion failure ext/opcache/jit/zend_jit_ir.c:8940
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants