Skip to content

Fuzzer php-fuzz-execute crashing case in _zend_is_inconsistent #19844

Closed

Description

@gal1ium

Description

Hi, we found a crashing test case when testing with the fuzzing driver php-fuzz-execute.

The following code:

<?php
class li0
{
    static $f;
    private $o;
    function stream_open()
    {
        return true;
    }
    function stream_read()
    {
    }
    function stream_eof()
    {
        include "li0://";
    }
    function stream_close()
    {
        [n];
    }
    function s()
    {
    }
}
str_repeat("", 0);
$s = "";
stream_wrapper_register("li0", li0::class);
include "li0://";

Resulted in this output:

/src/php-src/Zend/zend_hash.c(2678) : ht=0x1b3fcb8 is already destroyed
php-fuzz-execute: /src/php-src/Zend/zend_hash.c:73: void _zend_is_inconsistent(const HashTable *, const char *, int): Assertion `0' failed.

PHP Version

Commid id: d6300a3

Operating System

Linux

Activity

  1. iluuu1994 commented on Sep 15, 2025

    @iluuu1994
    Member

    This doesn't reproduce for me. Did you use any special compilation flags?

  2. gal1ium commented on Sep 15, 2025

    @gal1ium
    Author

    This is my flags based on oss-fuzz's build.sh

    export CFLAGS="-fno-sanitize=object-size"
    ./buildconf --force
    ./configure disable-all \
        --enable-debug-assertions \
        --enable-option-checking=fatal \
        --enable-fuzzer \
        --enable-exif \
        --without-pcre-jit \
        --disable-phpdbg \
        --disable-cgi \
        --with-pic
    make -j$(nproc)
    

    (BTW I observed different output between the fuzzer php-fuzz-execute and the program sapi/cli/php.)

  3. iluuu1994 commented on Sep 15, 2025

    @iluuu1994
    Member

    That worked, thanks! I'll check which of those flags is responsible.

  4. iluuu1994 commented on Sep 15, 2025

    @iluuu1994
    Member

    This is reproducible outside of the fuzzer with this example:

    class Test {
        function stream_open() {
            return true;
        }
    
        function stream_read() {}
    
        function stream_eof() {
            static $nested = false;
            if (!$nested) {
                $nested = true;
                include 'Test://';
            }
            trigger_error('Bail', E_USER_ERROR);
        }
    
        function stream_close() {
            trigger_error('Bail', E_USER_ERROR);
        }
    }
    
    stream_wrapper_register('Test', Test::class);
    include 'Test://';

    Thanks for the report.

  5. added a commit that references this issue on Nov 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions