diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index b01b99194a4d7..82d4975a76913 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -2236,17 +2236,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)); @@ -2267,6 +2261,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)); @@ -2283,6 +2279,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 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)