Skip to content

UAF in lexer with encoding translation and heredocs #16630

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

Closed
YuanchengJiang opened this issue Oct 29, 2024 · 5 comments
Closed

UAF in lexer with encoding translation and heredocs #16630

YuanchengJiang opened this issue Oct 29, 2024 · 5 comments

Comments

@YuanchengJiang
Copy link

Description

The following code:

<?php
$data3 = <<<DATA
<meta <meta name="keywords" content="php documentation">
$data4 = <<<DATA
<meta name="author" content="name"
<meta name="keywords" content="php documentation"
DATA;
foreach ($array as $html) {
}

Resulted in this output:

php: /home/phpfuzz/WorkSpace/diffphp/php-src/Zend/zend_execute.c:4341: void i_init_code_execute_data(zend_execute_data *, zend_op_array *, zval *): Assertion `op_array->fn_flags & (1 << 26)' failed.

And JIT 1231:

/Zend/Optimizer/zend_optimizer.c:1187: void zend_revert_pass_two(zend_op_array *): Assertion `(op_array->fn_flags & (1 << 25)) != 0' failed.
Aborted (core dumped)

It can cause segfault:

<?php
$data3 = <<<CODE
<meta <meta name="keywords" content="php documentation">
<meta name="author" content="name"
<meta name="keywords" content="php documentation"
CODE;
foreach ($array as $html) {
}

while it does not segfault in JIT

PHP Version

nightly

Operating System

ubuntu 22.04

@nielsdos
Copy link
Member

I tried both NTS and ZTS debug builds. Neither the non-JIT nor JIT example reproduces for me.
I just get:

Warning: Undefined variable $array in /run/media/niels/MoreData/php-src-multitasking/x.php on line 7
Warning: foreach() argument must be of type array|object, null given in /run/media/niels/MoreData/php-src-multitasking/x.php on line 7

Can you share the exact commit you tried this on, the configure options used, and the run options used please?

@YuanchengJiang
Copy link
Author

sorry forgot to append the config.

-d "zend.multibyte=On" -d "zend.script_encoding=ISO-8859-1" -d "internal_encoding=EUC-JP"

@nielsdos
Copy link
Member

That still doesn't reproduce anything for me.
Is the reproduction code complete? The flag it asserts on makes me think that you're missing something related to closures, or nested functions...

@YuanchengJiang
Copy link
Author

For the segv:

<?php
$data3 = <<<CODE
<meta <meta name="keywords" content="php documentation">
<meta name="author" content="name"
<meta name="keywords" content="php documentation"
CODE;
foreach ($array as $html) {
}

I just reproduced it in the latest commit. Compile:

CC="clang-15" CXX="clang++-15" ./configure --enable-debug --enable-address-sanitizer --enable-undefined-sanitizer --enable-re2c-cgoto --enable-fpm --enable-litespeed --enable-phpdbg-debug --enable-zts --enable-bcmath --enable-calendar --enable-dba --enable-dl-test --enable-exif --enable-ftp --enable-gd --enable-gd-jis-conv --enable-mbstring --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvmsg --with-zlib --with-bz2 --with-curl --with-enchant --with-ffi --with-gettext --with-gmp --with-mhash --with-ldap --with-libedit --with-readline --with-snmp --with-sodium --with-xsl --with-zip

Run: ./php-src/sapi/cli/php -d "zend.multibyte=On" -d "zend.script_encoding=ISO-8859-1" -d "internal_encoding=EUC-JP" /tmp/test.php

Output:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==70762==ERROR: AddressSanitizer: SEGV on unknown address 0x7fc24a06e400 (pc 0x7fc24a06e400 bp 0x7ffc9f9c4f90 sp 0x7ffc9f9c4ec8 T0)
==70762==The signal is caused by a READ memory access.
==70762==Hint: PC is at a non-executable region. Maybe a wild jump?
    #0 0x7fc24a06e400  (<unknown module>)
    #1 0x56503f6e8f42 in zend_execute /php-src/Zend/zend_vm_execute.h:64217:2
    #2 0x5650403ea701 in zend_execute_script /php-src/Zend/zend.c:1934:3
    #3 0x56503ecf8238 in php_execute_script_ex /php-src/main/main.c:2574:13
    #4 0x56503ecf92f8 in php_execute_script /php-src/main/main.c:2614:9
    #5 0x5650403fde76 in do_cli /php-src/sapi/cli/php_cli.c:938:5
    #6 0x5650403f8544 in main /php-src/sapi/cli/php_cli.c:1313:18
    #7 0x7fc250155d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==70762==ABORTING

@nielsdos
Copy link
Member

nielsdos commented Nov 6, 2024

This reproduces now, thanks.
This is a lexer bug, unrelated to opcache or JIT.

@nielsdos nielsdos self-assigned this Nov 6, 2024
@nielsdos nielsdos changed the title Assertion failure in Zend/zend_execute.c:4341 and Zend/Optimizer/zend_optimizer.c:1187 UAF in lexer with encoding translation and heredocs Nov 6, 2024
nielsdos added a commit to nielsdos/php-src that referenced this issue Nov 6, 2024
zend_save_lexical_state() can be nested multiple times, for example for
the parser initialization and then in the heredoc lexing. The input
should not be freed if we restore to the same filtered string.
nielsdos added a commit to nielsdos/php-src that referenced this issue Nov 14, 2024
zend_save_lexical_state() can be nested multiple times, for example for
the parser initialization and then in the heredoc lexing. The input
should not be freed if we restore to the same filtered string.
nielsdos added a commit that referenced this issue Nov 18, 2024
* PHP-8.2:
  Fix GH-16630: UAF in lexer with encoding translation and heredocs
nielsdos added a commit that referenced this issue Nov 18, 2024
* PHP-8.3:
  Fix GH-16630: UAF in lexer with encoding translation and heredocs
nielsdos added a commit that referenced this issue Nov 18, 2024
* PHP-8.4:
  Fix GH-16630: UAF in lexer with encoding translation and heredocs
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