[GIT-PULLS] [php-src] PR #22765: ext/filter: fix use-after-free in parse_str() with filter.default

[email protected] (iliaal) Thu, 16 Jul 2026 15:08:38 +0000
Newsgroups php.git-pulls
Message-ID <EAFNwlu9Z6tzNAkHLdRKmgba38aumn2P6IWWWxTK5QY@main.internal.php.net>
Pull Request: https://github.com/php/php-src/pull/22765
Author: iliaal

`php_sapi_filter()` re-exports parse_str() results through `Z_STRLEN`/`Z_STRVAL` without checking what type `php_zval_filter()` left behind. A failed validation frees the string and stores IS_FALSE, so the macros read the freed zend_string; a successful `FILTER_VALIDATE_INT` stores IS_LONG, so they dereference the integer as a pointer.

Reproducer, with filter.default set:

    php -d filter.default=int -r 'parse_str("a=1&b=notint", $out); var_dump($out);'

ASAN on 8.4, unpatched:

    ERROR: AddressSanitizer: heap-use-after-free
    READ of size 8 at ... in php_sapi_filter ext/filter/filter.c:353
      freed by      php_zval_filter   ext/filter/filter.c:275
      allocated at  php_sapi_filter   ext/filter/filter.c:338

    ERROR: AddressSanitizer: SEGV on unknown address 0x000000000011
      in php_sapi_filter ext/filter/filter.c:353

Convert with `zval_get_string()` before writing back. Present on 8.3 through master, targeting 8.4 as the lowest actively supported branch.