Skip to content

Fix GH-20403: Backport FETCH_OBJ_UNSET IS_UNDEF fix to PHP-8.4 - #24788

Open
Truta446 wants to merge 2 commits into
php:PHP-8.4from
Truta446:gh20403-backport
Open

Truta446 wants to merge 2 commits into
php:PHP-8.4from
Truta446:gh20403-backport

Conversation

@Truta446

Copy link
Copy Markdown

GH-20403 still reproduces on PHP-8.4 and PHP-8.5: unset($test::$instances[$x]->x) on an uninitialized typed static property reaches the IS_UNDEF container branch of zend_fetch_dimension_address() with a VAR operand, and zval_undefined_cv() reads past the CV names (heap-buffer-overflow under ASan, reproducer from @arnaud-lb in the issue).

As noted in the issue, this is already fixed on master/PHP-8.6 by 8b4ef3a (GH-19160, "Fix FETCH_OBJ_UNSET IS_UNDEF result"), which was only merged into master. This PR backports it to PHP-8.4.

  • Commit 1 is a cherry-pick of 8b4ef3a (authorship kept). It needed one adaptation: on PHP-8.4 zend_fetch_static_property_address_ex() returns zend_result, so the new early return is return FAILURE; instead of return NULL;. The two callers that can pass BP_VAR_IS/BP_VAR_UNSET (zend_fetch_static_prop_helper and ZEND_ISSET_ISEMPTY_STATIC_PROP) already treat FAILURE the same way master treats NULL. Zend/zend_vm_execute.h was regenerated with zend_vm_gen.php. NEWS left out.
  • Commit 2 adds Zend/tests/gh20403.phpt.

Verification:

  • gh20403.phpt fails under --asan on an unpatched PHP-8.5 build and passes with this patch.
  • PHP-8.4 debug + ASan: Zend/tests and tests/lang (5281 passed, 0 failed); Zend/tests and ext/opcache/tests with opcache.enable_cli=1, opcache.jit=tracing, opcache.protect_memory=1 (5301 passed, 0 failed).
  • PHP-8.4 debug ZTS: Zend/tests (5019 passed, 0 failed).

If you would rather keep this master-only, feel free to close; the test may still be useful there.

iluuu1994 and others added 2 commits October 27, 2026 11:40
UNSET_OBJ et al. do not expect to find IS_UNDEF results for IS_INDIRECT vars. To
solve this, return IS_NULL from FETCH_OBJ_UNSET when properties are
uninitialized. Do the same for FETCH_STATIC_PROP_IS, as we're otherwise copying
IS_UNDEF into the VAR result, which is not a valid value for VAR.

Fixes OSS-Fuzz #429429090
Closes phpGH-19160

(cherry picked from commit 8b4ef3a)
[Adapted to PHP-8.4, where zend_fetch_static_property_address_ex() returns
zend_result: return FAILURE instead of NULL.]
Unsetting a property of an undefined dimension of an uninitialized typed
static property passed a VAR operand to zval_undefined_cv(), which read past
the end of the CV names. Fixed by the previous commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants