From e68df0e7fff42f3de895c8d997801710f329c11f Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 30 Sep 2024 17:36:23 +0100 Subject: [PATCH 1/2] ext/ldap: Fix GH-16132 (Freeing pointer not allocated by ZMM) --- ext/ldap/ldap.c | 4 ++++ ext/ldap/tests/gh16132-1.phpt | 28 ++++++++++++++++++++++++++++ ext/ldap/tests/gh16132-2.phpt | 28 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 ext/ldap/tests/gh16132-1.phpt create mode 100644 ext/ldap/tests/gh16132-2.phpt diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index f0dd3ccb4c47d..ede60a298468c 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2181,6 +2181,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) convert_to_string(value); if (EG(exception)) { RETVAL_FALSE; + num_berval[i] = 0; + num_attribs = i + 1; goto cleanup; } ldap_mods[i]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval)); @@ -2197,6 +2199,8 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) } convert_to_string(ivalue); if (EG(exception)) { + num_berval[i] = j; + num_attribs = i + 1; RETVAL_FALSE; goto cleanup; } diff --git a/ext/ldap/tests/gh16132-1.phpt b/ext/ldap/tests/gh16132-1.phpt new file mode 100644 index 0000000000000..1979796446daa --- /dev/null +++ b/ext/ldap/tests/gh16132-1.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug GH-16132: Attempting to free pointer not allocated by ZMM +--EXTENSIONS-- +ldap +--FILE-- + new stdClass(), + 'attribute2' => [ + 'value1', + 'value2', + ], +]; +try { + var_dump(ldap_add($ldap, $valid_dn, $dict_key_value_not_string)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Object of class stdClass could not be converted to string diff --git a/ext/ldap/tests/gh16132-2.phpt b/ext/ldap/tests/gh16132-2.phpt new file mode 100644 index 0000000000000..eaf3bd67dfcb3 --- /dev/null +++ b/ext/ldap/tests/gh16132-2.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug GH-16132: Attempting to free pointer not allocated by ZMM +--EXTENSIONS-- +ldap +--FILE-- + 'value', + 'attribute2' => [ + 'value1', + new stdClass(), + ], +]; +try { + var_dump(ldap_add($ldap, $valid_dn, $dict_key_multi_value_not_list_of_strings2)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +Error: Object of class stdClass could not be converted to string From 61d5a76567517a1e2d05847f64e6f3a67483deb4 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 30 Sep 2024 17:58:22 +0100 Subject: [PATCH 2/2] ext/ldap: Fix GH-16136 (Memory leak in php_ldap_do_modify()) --- ext/ldap/ldap.c | 16 +++++----------- ext/ldap/tests/gh16136.phpt | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 ext/ldap/tests/gh16136.phpt diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index ede60a298468c..e33201f10d154 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2150,17 +2150,11 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) ldap_mods[i]->mod_type = estrndup(ZSTR_VAL(attribute), ZSTR_LEN(attribute)); } else { php_error_docref(NULL, E_WARNING, "Unknown attribute in the data"); - /* Free allocated memory */ - while (i >= 0) { - if (ldap_mods[i]->mod_type) { - efree(ldap_mods[i]->mod_type); - } - efree(ldap_mods[i]); - i--; - } - efree(num_berval); - efree(ldap_mods); - RETURN_FALSE; + RETVAL_FALSE; + num_berval[i] = 0; + num_attribs = i + 1; + ldap_mods[i]->mod_bvalues = NULL; + goto cleanup; } value = zend_hash_get_current_data(Z_ARRVAL_P(entry)); diff --git a/ext/ldap/tests/gh16136.phpt b/ext/ldap/tests/gh16136.phpt new file mode 100644 index 0000000000000..14f21e3e757f2 --- /dev/null +++ b/ext/ldap/tests/gh16136.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug GH-16136: Memory leak in php_ldap_do_modify() when entry is not a proper dictionary +--EXTENSIONS-- +ldap +--FILE-- + 'value', + 'not_key_entry', + 'attribute3' => [ + 'value1', + 'value2', + ], +]; +try { + var_dump(ldap_add($ldap, $valid_dn, $not_dict_of_attributes)); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Warning: ldap_add(): Unknown attribute in the data in %s on line %d +bool(false)