diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-04 09:41:27 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-04 14:23:14 +0200 |
commit | 2e218180efebeac4fe0fe3f36e39fce8fc513468 (patch) | |
tree | 75d028ac345289ff3a0211c146419c50492372c1 /Zend/zend_API.c | |
parent | c0d6b05b686767fcf6a858d5c039bee764655590 (diff) | |
download | php-git-2e218180efebeac4fe0fe3f36e39fce8fc513468.tar.gz |
Release call trampolines in zpp fcc
When using zpp 'f' or Z_PARAM_FUNC, if the fcc points to a call
trampoline release it immediately and force zend_call_function
to refetch it. This may require additional callability checks
if __call is used, but avoids the need to carefully free fcc
values in all internal functions -- in some cases this is not
simple, as a type error might be triggered by a later argument
in the same zpp call.
This fixes oss-fuzz #25390.
Closes GH-6073.
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r-- | Zend/zend_API.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 07ab456d1a..cc31a81a1c 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -825,6 +825,10 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec if (zend_fcall_info_init(arg, 0, fci, fcc, NULL, &is_callable_error) == SUCCESS) { ZEND_ASSERT(!is_callable_error); + /* Release call trampolines: The function may not get called, in which case + * the trampoline will leak. Force it to be refetched during + * zend_call_function instead. */ + zend_release_fcall_info_cache(fcc); break; } @@ -2979,8 +2983,8 @@ ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc) { zend_string_release_ex(fcc->function_handler->common.function_name, 0); } zend_free_trampoline(fcc->function_handler); + fcc->function_handler = NULL; } - fcc->function_handler = NULL; } static zend_always_inline bool zend_is_callable_check_func(int check_flags, zval *callable, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error) /* {{{ */ |