Skip to content

Commit d2ad57b

Browse files
committed
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. Allocate the array zeroed with ecalloc() so the unwritten slots are NULL. Reachable from userland via the $controls argument of ldap_search() and the other control-taking LDAP functions.
1 parent a480965 commit d2ad57b

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

ext/ldap/ldap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
563563
zval *sortkey, *tmp;
564564

565565
num_keys = zend_hash_num_elements(Z_ARRVAL_P(val));
566-
sort_keys = safe_emalloc((num_keys+1), sizeof(LDAPSortKey*), 0);
566+
sort_keys = ecalloc((num_keys+1), sizeof(LDAPSortKey*));
567567
tmpstrings1 = safe_emalloc(num_keys, sizeof(zend_string*), 0);
568568
tmpstrings2 = safe_emalloc(num_keys, sizeof(zend_string*), 0);
569569
num_tmpstrings1 = 0;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
ldap_search(): malformed sort control (sort key missing "attr") must not free uninitialized memory
3+
--EXTENSIONS--
4+
ldap
5+
--FILE--
6+
<?php
7+
// No server needed: the control array is validated before the search is sent.
8+
// A sort key missing "attr" makes php_ldap_control_from_array() bail mid-loop;
9+
// the failure cleanup must not walk/free the partially built sort_keys array.
10+
$ld = ldap_connect("ldap://127.0.0.1:389");
11+
12+
try {
13+
ldap_search($ld, "dc=example,dc=com", "(objectClass=*)", [], 0, -1, -1, LDAP_DEREF_NEVER, [
14+
[
15+
'oid' => LDAP_CONTROL_SORTREQUEST,
16+
'value' => [
17+
['attr' => 'cn'],
18+
['reverse' => true],
19+
],
20+
],
21+
]);
22+
} catch (\ValueError $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
26+
echo "ok\n";
27+
?>
28+
--EXPECT--
29+
ldap_search(): Sort key list must have an "attr" key
30+
ok

0 commit comments

Comments
 (0)