Skip to content

Stack overflow in zend_fiber_execute() triggered by too small stack when using ASAN #20483

Closed

Description

@vi3tL0u1s

Description

The following code:

<?php
class a {
    function __destruct() {
        ini_set("fiber.stack_size","9690x-D");
        $fiber = new Fiber(function() {});
        try {
            $fiber->start();
        } catch (Throwable $e) {}
    }
}
new a;

Command:

USE_ZEND_ALLOC=0 ./php-src/sapi/cli/php poc.php

Resulted in this output:

Warning: Invalid "fiber.stack_size" setting. Invalid quantity "9690x-D": unknown multiplier "D", interpreting as "9690" for backwards compatibility in /path/to/poc.php on line 4
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3169464==ERROR: AddressSanitizer: stack-overflow on address 0x7f4d9000cb08 (pc 0x55f82568615b bp 0x7f4d9000d330 sp 0x7f4d9000cb00 T0)
    #0 0x55f82568615b in malloc (/path/to/php-src/sapi/cli/php+0x68615b) (BuildId: 78daf5f832c7fdbb3fc64cdca7de50663e951019)
    #1 0x55f826c261b3 in __zend_malloc /path/to/php-src/Zend/zend_alloc.c:3543:14
    #2 0x55f826c25b40 in _emalloc /path/to/php-src/Zend/zend_alloc.c:2780:10
    #3 0x55f82719b54f in _smart_string_alloc /path/to/php-src/Zend/zend_smart_str.c:172:13
    #4 0x55f826a2fe4c in smart_string_alloc /path/to/php-src/Zend/zend_smart_string.h:62:4
    #5 0x55f826a2fb0e in smart_string_appendc_ex /path/to/php-src/Zend/zend_smart_string.h:83:14
    #6 0x55f826a282c3 in xbuf_format_converter /path/to/php-src/main/spprintf.c:220:4
    #7 0x55f826a27f79 in php_printf_to_smart_string /path/to/php-src/main/spprintf.c:750:2
    #8 0x55f8271ca54d in zend_vspprintf /path/to/php-src/Zend/zend.c:294:2
    #9 0x55f8271d5064 in zend_throw_error /path/to/php-src/Zend/zend.c:1828:2
    #10 0x55f826d91b21 in zend_call_stack_size_error /path/to/php-src/Zend/zend_execute.c:2618:2
    #11 0x55f826da23e5 in execute_ex /path/to/php-src/Zend/zend_vm_execute.h:116196:3
    #12 0x55f826d7cac1 in zend_call_function /path/to/php-src/Zend/zend_execute_API.c:1014:3
    #13 0x55f827008a63 in zend_fiber_execute /path/to/php-src/Zend/zend_fibers.c:604:3
    #14 0x55f827006122 in zend_fiber_trampoline /path/to/php-src/Zend/zend_fibers.c:387:2
    #15 0x55f8269c302e in trampoline /path/to/php-src/Zend/asm/make_x86_64_sysv_elf_gas.S:177

SUMMARY: AddressSanitizer: stack-overflow (/path/to/php-src/sapi/cli/php+0x68615b) (BuildId: 78daf5f832c7fdbb3fc64cdca7de50663e951019) in malloc
==3169464==ABORTING

Commit:

9cd367362da5442861f30d3b41e967d641b90cbd

Build configuration:

CC="clang" CXX="clang++" CFLAGS="-fsanitize=address -g -O0" CXXFLAGS="-fsanitize=address -g -O0" LDFLAGS="-fsanitize=address" ./buildconf --force && ./configure --enable-debug --enable-address-sanitizer --disable-shared --with-pic --enable-mbstring --with-zlib

PHP Version

PHP 8.6.0-dev (cli) (built: Nov 14 2025 16:07:53) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.6.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.6.0-dev, Copyright (c), by Zend Technologies

Operating System

Ubuntu 22.04

Activity

  1. changed the title [-]Stack overflow in zend_fiber_execute() triggered by invalid fiber.stack_size configuration during destructor execution[/-] [+]Stack overflow in zend_fiber_execute() triggered by invalid fiber.stack_size configuration during __destruct()[/+] on Nov 14, 2025
  2. devnexen commented on Nov 14, 2025

    @devnexen
    Member

    can be reproduced even w/o USE_ZEND_ALLOC=0

  3. devnexen commented on Nov 14, 2025

    @devnexen
    Member

    ironic where it happens though :)

  4. devnexen commented on Nov 15, 2025

    @devnexen
    Member

    The point is that the stack size is set too small

    would handling this fiber.stack_size update callback be the appropriate approach ?

  5. ndossche commented on Nov 15, 2025

    @ndossche
    Member

    Did you remove my comment? 🤔
    Anyway, I believe this is actually just a false positive in a sense. ASAN might require more stack size. So the minimum boundary should be updated most likely.
    We already have a check for a minimum boundary here:

    php-src/Zend/zend_fibers.c

    Lines 210 to 215 in b3061df

    const size_t minimum_stack_size = page_size + ZEND_FIBER_GUARD_PAGES * page_size;
    if (size < minimum_stack_size) {
    zend_throw_exception_ex(NULL, 0, "Fiber stack size is too small, it needs to be at least %zu bytes", minimum_stack_size);
    return NULL;
    }

    I also see that we do checks here:

    php-src/Zend/zend.c

    Lines 243 to 246 in b3061df

    if (tmp < 0) {
    zend_error(E_WARNING, "fiber.stack_size must be a positive number");
    return FAILURE;
    }

    I think it's probably best to move all checks to the INI handler; and then also raise the minimum if ASAN is active (e.g. multiply by 3 or something like that). Also because the checks are moved to the INI handler, then you'd need to change the exception throwing to emitting a warning because not at all points in time is it possible to throw in an INI handler.

  6. devnexen commented on Nov 15, 2025

    @devnexen
    Member

    Did you remove my comment? 🤔

    No that comes from the other ticket.

  7. ndossche commented on Nov 15, 2025

    @ndossche
    Member

    Oh right of course, apologies

  8. devnexen commented on Nov 15, 2025

    @devnexen
    Member

    I think it's probably best to move all checks to the INI handler; and then also raise the minimum if ASAN is active (e.g. multiply by 3 or something like that). Also because the checks are moved to the INI handler, then you'd need to change the exception throwing to emitting a warning because not at all points in time is it possible to throw in an INI handler.

    For sure in the callback however moving everything in it seems a "master move" to me, I was thinking just checking minimum value in the callback for stable branches.

  9. ndossche commented on Nov 15, 2025

    @ndossche
    Member

    That should work

  10. self-assigned this
    on Nov 15, 2025
  11. added a commit that references this issue on Nov 15, 2025
    51f15da
  12. changed the title [-]Stack overflow in zend_fiber_execute() triggered by invalid fiber.stack_size configuration during __destruct()[/-] [+]Stack overflow in zend_fiber_execute() triggered by too small stack when using ASAN[/+] on Nov 15, 2025
  13. added 2 commits that reference this issue on Nov 15, 2025
    d2c5b3b
    e3c2301
  14. added 2 commits that reference this issue on Nov 15, 2025
    01bca99
    48aefb5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions