From 4fad6cd315b5814f18957128f09e70f3bb5b1f41 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 16 Jun 2026 15:01:55 -0400 Subject: [PATCH] Fix freeing uninitialized memory in LDAP sort control parsing _php_ldap_control_from_array() allocated the sort_keys array with safe_emalloc() and only wrote its NULL terminator after the per-key loop finished. A sort key missing the "attr" entry makes the loop bail out early, leaving the array partially uninitialized; the failure cleanup then walks it as a NULL-terminated list and calls efree() on the uninitialized slots. Zero the array after allocation so the unwritten slots are NULL. Reachable from userland via the $controls argument of ldap_search() and the other control-taking LDAP functions. Closes GH-22342 --- ext/ldap/ldap.c | 1 + .../tests/ldap_sort_control_missing_attr.phpt | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 ext/ldap/tests/ldap_sort_control_missing_attr.phpt diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index e6ea4d908af5..2b3cb0e8a706 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -564,6 +564,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra num_keys = zend_hash_num_elements(Z_ARRVAL_P(val)); sort_keys = safe_emalloc((num_keys+1), sizeof(LDAPSortKey*), 0); + memset(sort_keys, 0, (num_keys+1) * sizeof(LDAPSortKey*)); tmpstrings1 = safe_emalloc(num_keys, sizeof(zend_string*), 0); tmpstrings2 = safe_emalloc(num_keys, sizeof(zend_string*), 0); num_tmpstrings1 = 0; diff --git a/ext/ldap/tests/ldap_sort_control_missing_attr.phpt b/ext/ldap/tests/ldap_sort_control_missing_attr.phpt new file mode 100644 index 000000000000..0d6c3921f008 --- /dev/null +++ b/ext/ldap/tests/ldap_sort_control_missing_attr.phpt @@ -0,0 +1,30 @@ +--TEST-- +ldap_search(): malformed sort control (sort key missing "attr") must not free uninitialized memory +--EXTENSIONS-- +ldap +--FILE-- + LDAP_CONTROL_SORTREQUEST, + 'value' => [ + ['attr' => 'cn'], + ['reverse' => true], + ], + ], + ]); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "ok\n"; +?> +--EXPECT-- +ldap_search(): Sort key list must have an "attr" key +ok