Skip to content

Commit fce4c8f

Browse files
committed
ext/ldap: fix crash in ldap_exop_sync() when $response_data is omitted
ldap_exop_sync() always takes the synchronous branch of php_ldap_exop(), which assigns $response_data unconditionally. When the argument is not passed, retdata is NULL and ZEND_TRY_ASSIGN_REF_STRINGL()/ ZEND_TRY_ASSIGN_REF_EMPTY_STRING() dereference it, so any successful ldap_exop_sync($ldap, $oid) call segfaults. Guard the assignment the way the $response_oid one already is.
1 parent 26097c8 commit fce4c8f

2 files changed

Lines changed: 26 additions & 2 deletions

File tree

ext/ldap/ldap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4101,10 +4101,12 @@ static void php_ldap_exop(INTERNAL_FUNCTION_PARAMETERS, bool force_sync) {
41014101
}
41024102

41034103
if (lretdata) {
4104-
ZEND_TRY_ASSIGN_REF_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
4104+
if (retdata) {
4105+
ZEND_TRY_ASSIGN_REF_STRINGL(retdata, lretdata->bv_val, lretdata->bv_len);
4106+
}
41054107
ldap_memfree(lretdata->bv_val);
41064108
ldap_memfree(lretdata);
4107-
} else {
4109+
} else if (retdata) {
41084110
ZEND_TRY_ASSIGN_REF_EMPTY_STRING(retdata);
41094111
}
41104112

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
ldap_exop_sync() - without the response_data argument
3+
--EXTENSIONS--
4+
ldap
5+
--SKIPIF--
6+
<?php require_once('skipifbindfailure.inc'); ?>
7+
--FILE--
8+
<?php
9+
require "connect.inc";
10+
11+
$link = ldap_connect_and_bind($uri, $user, $passwd, $protocol_version);
12+
13+
var_dump(
14+
ldap_exop_sync($link, LDAP_EXOP_WHO_AM_I),
15+
ldap_exop_sync($link, LDAP_EXOP_WHO_AM_I, null, null, $retdata),
16+
$retdata
17+
);
18+
?>
19+
--EXPECTF--
20+
bool(true)
21+
bool(true)
22+
string(%d) "dn:%s"

0 commit comments

Comments
 (0)