Skip to content

str_starts_with(): frameless handler reads argument 2 after argument 1 coercion #25413

Closed as not planned

Description

@lacatoire

The frameless handler of str_starts_with() takes a raw pointer to argument 2 before argument 1 is coerced. If the coercion runs user code that turns that variable into a reference, argument 2 is rejected with a TypeError, or a freed zend_reference is read (heap-use-after-free under ASAN with unset()).

class H { function __toString() { global $n; $n = $n; return "abc"; } }
$n = "a";
var_dump(str_starts_with(new H, $n));

Actual: TypeError: str_starts_with(): Argument #2 ($needle) must be of type string, string given
Expected: bool(true) (what $f = 'str_starts_with'; $f(new H, $n) returns).

Only direct calls with a CV as argument 2 are affected (FRAMELESS_ICALL_2, Z_FLF_PARAM_STR in Zend/zend_frameless_function.h). Reproduced on PHP 8.5.

Activity

  1. ndossche commented on Nov 13, 2026

    @ndossche
    Member

    These kind of clobbering issues fall into a broader category, see for example #20316
    These should be fixed together with a unified fix for engine interruption.
    This is artificial code anyway, not something a person would really write.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions