Skip to content

Commit 98457b6

Browse files
committed
Fix some leaks in ldap
The result of zval_get_string() needs to be released. In some places where it is inconvenient to manage, I went back to convert_to_string. It is safe in those places due to existing array separations. Also fix a preexisting leak when getting controls, the previous value was not destroyed.
1 parent 5d2fe48 commit 98457b6

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

ext/ldap/ldap.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array,
279279
static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* array)
280280
{
281281
zval* val;
282-
zend_string *control_oid = NULL;
282+
zend_string *control_oid;
283283
int control_iscritical = 0, rc = LDAP_SUCCESS;
284284
char** ldap_attrs = NULL;
285285
LDAPSortKey** sort_keys = NULL;
@@ -312,7 +312,8 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
312312
} else {
313313
tmpstring = zval_get_string(val);
314314
if (EG(exception)) {
315-
return -1;
315+
rc = -1;
316+
goto failure;
316317
}
317318
control_value->bv_val = ZSTR_VAL(tmpstring);
318319
control_value->bv_len = ZSTR_LEN(tmpstring);
@@ -369,6 +370,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
369370
php_error_docref(NULL, E_WARNING, "Failed to create assert control value: %s (%d)", ldap_err2string(rc), rc);
370371
}
371372
}
373+
zend_string_release(assert);
372374
}
373375
} else if (strcmp(ZSTR_VAL(control_oid), LDAP_CONTROL_VALUESRETURNFILTER) == 0) {
374376
zval* tmp;
@@ -585,6 +587,10 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
585587
}
586588

587589
failure:
590+
zend_string_release(control_oid);
591+
if (tmpstring != NULL) {
592+
zend_string_release(tmpstring);
593+
}
588594
if (control_value != NULL) {
589595
ber_memfree(control_value);
590596
control_value = NULL;
@@ -1456,7 +1462,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14561462
{
14571463
zval *link, *base_dn, *filter, *attrs = NULL, *attr, *serverctrls = NULL;
14581464
zend_long attrsonly, sizelimit, timelimit, deref;
1459-
zend_string *ldap_filter = NULL, *ldap_base_dn = NULL, *tmpstring;
1465+
zend_string *ldap_filter = NULL, *ldap_base_dn = NULL;
14601466
char **ldap_attrs = NULL;
14611467
ldap_linkdata *ld = NULL;
14621468
LDAPMessage *ldap_res;
@@ -1465,7 +1471,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14651471
int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1;
14661472
int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS();
14671473

1468-
if (zend_parse_parameters(argcount, "zzz|alllla", &link, &base_dn, &filter, &attrs, &attrsonly,
1474+
if (zend_parse_parameters(argcount, "zzz|alllla/", &link, &base_dn, &filter, &attrs, &attrsonly,
14691475
&sizelimit, &timelimit, &deref, &serverctrls) == FAILURE) {
14701476
return;
14711477
}
@@ -1492,12 +1498,12 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
14921498
goto cleanup;
14931499
}
14941500

1495-
tmpstring = zval_get_string(attr);
1501+
convert_to_string(attr);
14961502
if (EG(exception)) {
14971503
ret = 0;
14981504
goto cleanup;
14991505
}
1500-
ldap_attrs[i] = ZSTR_VAL(tmpstring);
1506+
ldap_attrs[i] = Z_STRVAL_P(attr);
15011507
}
15021508
ldap_attrs[num_attribs] = NULL;
15031509
default:
@@ -1680,6 +1686,12 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope)
16801686
/* Restoring previous options */
16811687
php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref);
16821688
}
1689+
if (ldap_filter) {
1690+
zend_string_release(ldap_filter);
1691+
}
1692+
if (ldap_base_dn) {
1693+
zend_string_release(ldap_base_dn);
1694+
}
16831695
if (ldap_attrs != NULL) {
16841696
efree(ldap_attrs);
16851697
}
@@ -2213,7 +2225,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22132225
int i, j, num_attribs, num_values, msgid;
22142226
size_t dn_len;
22152227
int *num_berval;
2216-
zend_string *attribute, *tmpstring;
2228+
zend_string *attribute;
22172229
zend_ulong index;
22182230
int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */
22192231

@@ -2274,14 +2286,14 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22742286

22752287
/* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */
22762288
if ((num_values == 1) && (Z_TYPE_P(value) != IS_ARRAY)) {
2277-
tmpstring = zval_get_string(value);
2289+
convert_to_string(value);
22782290
if (EG(exception)) {
22792291
RETVAL_FALSE;
22802292
goto cleanup;
22812293
}
22822294
ldap_mods[i]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval));
2283-
ldap_mods[i]->mod_bvalues[0]->bv_val = ZSTR_VAL(tmpstring);
2284-
ldap_mods[i]->mod_bvalues[0]->bv_len = ZSTR_LEN(tmpstring);
2295+
ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_P(value);
2296+
ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value);
22852297
} else {
22862298
for (j = 0; j < num_values; j++) {
22872299
if ((ivalue = zend_hash_index_find(Z_ARRVAL_P(value), j)) == NULL) {
@@ -2291,14 +2303,14 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
22912303
RETVAL_FALSE;
22922304
goto cleanup;
22932305
}
2294-
tmpstring = zval_get_string(ivalue);
2306+
convert_to_string(ivalue);
22952307
if (EG(exception)) {
22962308
RETVAL_FALSE;
22972309
goto cleanup;
22982310
}
22992311
ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval));
2300-
ldap_mods[i]->mod_bvalues[j]->bv_val = ZSTR_VAL(tmpstring);
2301-
ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(tmpstring);
2312+
ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_P(ivalue);
2313+
ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(ivalue);
23022314
}
23032315
}
23042316
ldap_mods[i]->mod_bvalues[num_values] = NULL;
@@ -2823,6 +2835,7 @@ PHP_FUNCTION(ldap_modify_batch)
28232835
/* fill it */
28242836
ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(modval);
28252837
ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(ZSTR_VAL(modval), ZSTR_LEN(modval));
2838+
zend_string_release(modval);
28262839
}
28272840

28282841
/* NULL-terminate values */
@@ -3187,6 +3200,7 @@ PHP_FUNCTION(ldap_get_option)
31873200
}
31883201
RETURN_FALSE;
31893202
}
3203+
zval_ptr_dtor(retval);
31903204
_php_ldap_controls_to_array(ld->link, ctrls, retval, 1);
31913205
} break;
31923206
/* options not implemented
@@ -3331,8 +3345,10 @@ PHP_FUNCTION(ldap_set_option)
33313345
RETURN_FALSE;
33323346
}
33333347
if (ldap_set_option(ldap, option, ZSTR_VAL(val))) {
3348+
zend_string_release(val);
33343349
RETURN_FALSE;
33353350
}
3351+
zend_string_release(val);
33363352
} break;
33373353
/* options with boolean value */
33383354
case LDAP_OPT_REFERRALS:

0 commit comments

Comments
 (0)