From 2df9f32732e932b077603262d5c77416f1da5814 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 15 Dec 2024 22:11:37 +0000 Subject: [PATCH] ext/pcntl: Fix memory leak in cleanup code of pcntl_exec() --- NEWS | 4 +++ ext/pcntl/pcntl.c | 9 ++++--- .../tests/pcntl_exec_invalid_strings.phpt | 25 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 ext/pcntl/tests/pcntl_exec_invalid_strings.phpt diff --git a/NEWS b/NEWS index 8caf8cc4573..437c704c25e 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,10 @@ PHP NEWS - Opcache: . opcache_get_configuration() properly reports jit_prof_threshold. (cmb) +- PCNTL: + . Fix memory leak in cleanup code of pcntl_exec() when a non stringable + value is encountered past the first entry. (Girgias) + - PgSql: . Fixed bug GH-17158 (pg_fetch_result Shows Incorrect ArgumentCountError Message when Called With 1 Argument). (nielsdos) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 19460ad8b53..adb94af2fb4 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -540,7 +540,9 @@ PHP_FUNCTION(pcntl_exec) envs_hash = Z_ARRVAL_P(envs); envc = zend_hash_num_elements(envs_hash); - pair = envp = safe_emalloc((envc + 1), sizeof(char *), 0); + size_t envp_len = (envc + 1); + pair = envp = safe_emalloc(envp_len, sizeof(char *), 0); + memset(envp, 0, sizeof(char *) * envp_len); ZEND_HASH_FOREACH_KEY_VAL(envs_hash, key_num, key, element) { if (envi >= envc) break; if (!key) { @@ -551,9 +553,7 @@ PHP_FUNCTION(pcntl_exec) if (!try_convert_to_string(element)) { zend_string_release(key); - efree(argv); - efree(envp); - RETURN_THROWS(); + goto cleanup_env_vars; } /* Length of element + equal sign + length of key + null */ @@ -576,6 +576,7 @@ PHP_FUNCTION(pcntl_exec) php_error_docref(NULL, E_WARNING, "Error has occurred: (errno %d) %s", errno, strerror(errno)); } +cleanup_env_vars: /* Cleanup */ for (pair = envp; *pair != NULL; pair++) efree(*pair); efree(envp); diff --git a/ext/pcntl/tests/pcntl_exec_invalid_strings.phpt b/ext/pcntl/tests/pcntl_exec_invalid_strings.phpt new file mode 100644 index 00000000000..7b2b5e51b8f --- /dev/null +++ b/ext/pcntl/tests/pcntl_exec_invalid_strings.phpt @@ -0,0 +1,25 @@ +--TEST-- +pcntl_exec(): Test cleanup after non-stringable array value has been encountered for $args and $env_vars. +--EXTENSIONS-- +pcntl +--FILE-- +getMessage(), "\n"; +} + +try { + pcntl_exec( + 'cmd', + ['-n'], + ['var1' => 'value1', 'var2' => new stdClass()], + ); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Error: Object of class stdClass could not be converted to string +Error: Object of class stdClass could not be converted to string