Skip to content

Commit bb4e66c

Browse files
committed
fix memory leaks in _php_ldap_control_from_array()/control_value
1 parent 6edab36 commit bb4e66c

File tree

1 file changed

+39
-62
lines changed

1 file changed

+39
-62
lines changed

ext/ldap/ldap.c

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -302,23 +302,18 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
302302
}
303303

304304
BerElement *ber = NULL;
305-
struct berval *control_value = NULL;
305+
struct berval control_value = { 0, NULL };
306+
int control_value_alloc = 0;
306307

307308
if ((val = zend_hash_str_find(Z_ARRVAL_P(array), "value", sizeof("value") - 1)) != NULL) {
308309
if (Z_TYPE_P(val) != IS_ARRAY) {
309-
control_value = ber_memalloc(sizeof * control_value);
310-
if (control_value == NULL) {
310+
tmpstring = zval_get_string(val);
311+
if (EG(exception)) {
311312
rc = -1;
312-
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
313-
} else {
314-
tmpstring = zval_get_string(val);
315-
if (EG(exception)) {
316-
rc = -1;
317-
goto failure;
318-
}
319-
control_value->bv_val = ZSTR_VAL(tmpstring);
320-
control_value->bv_len = ZSTR_LEN(tmpstring);
313+
goto failure;
321314
}
315+
control_value.bv_val = ZSTR_VAL(tmpstring);
316+
control_value.bv_len = ZSTR_LEN(tmpstring);
322317
} else if (strcmp(ZSTR_VAL(control_oid), LDAP_CONTROL_PAGEDRESULTS) == 0) {
323318
zval* tmp;
324319
int pagesize = 1;
@@ -335,15 +330,11 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
335330
cookie.bv_val = ZSTR_VAL(tmpstring);
336331
cookie.bv_len = ZSTR_LEN(tmpstring);
337332
}
338-
control_value = ber_memalloc(sizeof * control_value);
339-
if (control_value == NULL) {
340-
rc = -1;
341-
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
342-
} else {
343-
rc = ldap_create_page_control_value(ld, pagesize, &cookie, control_value);
344-
if (rc != LDAP_SUCCESS) {
345-
php_error_docref(NULL, E_WARNING, "Failed to create paged result control value: %s (%d)", ldap_err2string(rc), rc);
346-
}
333+
/* ldap_create_page_control_value() allocates memory for control_value.bv_val */
334+
control_value_alloc = 1;
335+
rc = ldap_create_page_control_value(ld, pagesize, &cookie, &control_value);
336+
if (rc != LDAP_SUCCESS) {
337+
php_error_docref(NULL, E_WARNING, "Failed to create paged result control value: %s (%d)", ldap_err2string(rc), rc);
347338
}
348339
} else if (strcmp(ZSTR_VAL(control_oid), LDAP_CONTROL_ASSERT) == 0) {
349340
zval* tmp;
@@ -357,19 +348,15 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
357348
rc = -1;
358349
goto failure;
359350
}
360-
control_value = ber_memalloc(sizeof * control_value);
361-
if (control_value == NULL) {
362-
rc = -1;
363-
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
364-
} else {
365-
/* ldap_create_assertion_control_value does not reset ld_errno, we need to do it ourselves
366-
See http://www.openldap.org/its/index.cgi/Incoming?id=8674 */
367-
int success = LDAP_SUCCESS;
368-
ldap_set_option(ld, LDAP_OPT_RESULT_CODE, &success);
369-
rc = ldap_create_assertion_control_value(ld, ZSTR_VAL(assert), control_value);
370-
if (rc != LDAP_SUCCESS) {
371-
php_error_docref(NULL, E_WARNING, "Failed to create assert control value: %s (%d)", ldap_err2string(rc), rc);
372-
}
351+
/* ldap_create_assertion_control_value does not reset ld_errno, we need to do it ourselves
352+
See http://www.openldap.org/its/index.cgi/Incoming?id=8674 */
353+
int success = LDAP_SUCCESS;
354+
ldap_set_option(ld, LDAP_OPT_RESULT_CODE, &success);
355+
/* ldap_create_assertion_control_value() allocates memory for control_value.bv_val */
356+
control_value_alloc = 1;
357+
rc = ldap_create_assertion_control_value(ld, ZSTR_VAL(assert), &control_value);
358+
if (rc != LDAP_SUCCESS) {
359+
php_error_docref(NULL, E_WARNING, "Failed to create assert control value: %s (%d)", ldap_err2string(rc), rc);
373360
}
374361
zend_string_release(assert);
375362
}
@@ -380,8 +367,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
380367
php_error_docref(NULL, E_WARNING, "Filter missing from control value array");
381368
} else {
382369
ber = ber_alloc_t(LBER_USE_DER);
383-
control_value = ber_memalloc(sizeof * control_value);
384-
if ((control_value == NULL) || (ber == NULL)) {
370+
if (ber == NULL) {
385371
rc = -1;
386372
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
387373
} else {
@@ -393,7 +379,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
393379
if (ldap_put_vrFilter(ber, ZSTR_VAL(tmpstring)) == -1) {
394380
rc = -1;
395381
php_error_docref(NULL, E_WARNING, "Failed to create control value: Bad ValuesReturnFilter: %s", ZSTR_VAL(tmpstring));
396-
} else if (ber_flatten2(ber, control_value, 0) == -1) {
382+
} else if (ber_flatten2(ber, &control_value, control_value_alloc) == -1) {
397383
rc = -1;
398384
}
399385
}
@@ -406,8 +392,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
406392
} else {
407393
ber = ber_alloc_t(LBER_USE_DER);
408394

409-
control_value = ber_memalloc(sizeof * control_value);
410-
if ((control_value == NULL) || (ber == NULL)) {
395+
if (ber == NULL) {
411396
rc = -1;
412397
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
413398
} else {
@@ -443,7 +428,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
443428
php_error_docref(NULL, E_WARNING, "Failed to encode attribute list");
444429
} else {
445430
int err;
446-
err = ber_flatten2(ber, control_value, 0);
431+
err = ber_flatten2(ber, &control_value, control_value_alloc);
447432
if (err < 0) {
448433
rc = -1;
449434
php_error_docref(NULL, E_WARNING, "Failed to encode control value (%d)", err);
@@ -502,15 +487,11 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
502487
}
503488
}
504489
sort_keys[num_keys] = NULL;
505-
control_value = ber_memalloc(sizeof * control_value);
506-
if (control_value == NULL) {
507-
rc = -1;
508-
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
509-
} else {
510-
rc = ldap_create_sort_control_value(ld, sort_keys, control_value);
511-
if (rc != LDAP_SUCCESS) {
512-
php_error_docref(NULL, E_WARNING, "Failed to create sort control value: %s (%d)", ldap_err2string(rc), rc);
513-
}
490+
/* ldap_create_sort_control_value() allocates memory for control_value.bv_val */
491+
control_value_alloc = 1;
492+
rc = ldap_create_sort_control_value(ld, sort_keys, &control_value);
493+
if (rc != LDAP_SUCCESS) {
494+
php_error_docref(NULL, E_WARNING, "Failed to create sort control value: %s (%d)", ldap_err2string(rc), rc);
514495
}
515496
} else if (strcmp(ZSTR_VAL(control_oid), LDAP_CONTROL_VLVREQUEST) == 0) {
516497
zval* tmp;
@@ -572,15 +553,11 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
572553
vlvInfo.ldvlv_context = NULL;
573554
}
574555

575-
control_value = ber_memalloc(sizeof * control_value);
576-
if (control_value == NULL) {
577-
rc = -1;
578-
php_error_docref(NULL, E_WARNING, "Failed to allocate control value");
579-
} else {
580-
rc = ldap_create_vlv_control_value(ld, &vlvInfo, control_value);
581-
if (rc != LDAP_SUCCESS) {
582-
php_error_docref(NULL, E_WARNING, "Failed to create VLV control value: %s (%d)", ldap_err2string(rc), rc);
583-
}
556+
/* ldap_create_vlv_control_value() allocates memory for control_value.bv_val */
557+
control_value_alloc = 1;
558+
rc = ldap_create_vlv_control_value(ld, &vlvInfo, &control_value);
559+
if (rc != LDAP_SUCCESS) {
560+
php_error_docref(NULL, E_WARNING, "Failed to create VLV control value: %s (%d)", ldap_err2string(rc), rc);
584561
}
585562
} else {
586563
php_error_docref(NULL, E_WARNING, "Control OID %s does not expect an array as value", ZSTR_VAL(control_oid));
@@ -589,7 +566,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
589566
}
590567

591568
if (rc == LDAP_SUCCESS) {
592-
rc = ldap_control_create(ZSTR_VAL(control_oid), control_iscritical, control_value, 1, ctrl);
569+
rc = ldap_control_create(ZSTR_VAL(control_oid), control_iscritical, &control_value, 1, ctrl);
593570
}
594571

595572
failure:
@@ -611,9 +588,9 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra
611588
}
612589
efree(tmpstrings2);
613590
}
614-
if (control_value != NULL) {
615-
ber_memfree(control_value);
616-
control_value = NULL;
591+
if (control_value.bv_val != NULL && control_value_alloc != 0) {
592+
/* ber_memfree_x(control_value.bv_val, ctx) ???*/
593+
ber_memfree(control_value.bv_val);
617594
}
618595
if (ber != NULL) {
619596
ber_free(ber, 1);

0 commit comments

Comments
 (0)