diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-14 11:11:24 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-14 11:11:24 +0200 |
commit | 98457b6d60a79db44fe1ac7cd6b100f8cb6cf940 (patch) | |
tree | 0946577171299b105c38eb047aa47a4778122e11 | |
parent | 5d2fe48785b6d24102ff53e78631cba7f2aefbef (diff) | |
download | php-git-98457b6d60a79db44fe1ac7cd6b100f8cb6cf940.tar.gz |
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.
-rw-r--r-- | ext/ldap/ldap.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index f68f0bded0..a348b6e7b1 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -279,7 +279,7 @@ static void _php_ldap_control_to_array(LDAP *ld, LDAPControl* ctrl, zval* array, static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* array) { zval* val; - zend_string *control_oid = NULL; + zend_string *control_oid; int control_iscritical = 0, rc = LDAP_SUCCESS; char** ldap_attrs = NULL; LDAPSortKey** sort_keys = NULL; @@ -312,7 +312,8 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra } else { tmpstring = zval_get_string(val); if (EG(exception)) { - return -1; + rc = -1; + goto failure; } control_value->bv_val = ZSTR_VAL(tmpstring); control_value->bv_len = ZSTR_LEN(tmpstring); @@ -369,6 +370,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra php_error_docref(NULL, E_WARNING, "Failed to create assert control value: %s (%d)", ldap_err2string(rc), rc); } } + zend_string_release(assert); } } else if (strcmp(ZSTR_VAL(control_oid), LDAP_CONTROL_VALUESRETURNFILTER) == 0) { zval* tmp; @@ -585,6 +587,10 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra } failure: + zend_string_release(control_oid); + if (tmpstring != NULL) { + zend_string_release(tmpstring); + } if (control_value != NULL) { ber_memfree(control_value); control_value = NULL; @@ -1456,7 +1462,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) { zval *link, *base_dn, *filter, *attrs = NULL, *attr, *serverctrls = NULL; zend_long attrsonly, sizelimit, timelimit, deref; - zend_string *ldap_filter = NULL, *ldap_base_dn = NULL, *tmpstring; + zend_string *ldap_filter = NULL, *ldap_base_dn = NULL; char **ldap_attrs = NULL; ldap_linkdata *ld = NULL; LDAPMessage *ldap_res; @@ -1465,7 +1471,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argcount, "zzz|alllla", &link, &base_dn, &filter, &attrs, &attrsonly, + if (zend_parse_parameters(argcount, "zzz|alllla/", &link, &base_dn, &filter, &attrs, &attrsonly, &sizelimit, &timelimit, &deref, &serverctrls) == FAILURE) { return; } @@ -1492,12 +1498,12 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) goto cleanup; } - tmpstring = zval_get_string(attr); + convert_to_string(attr); if (EG(exception)) { ret = 0; goto cleanup; } - ldap_attrs[i] = ZSTR_VAL(tmpstring); + ldap_attrs[i] = Z_STRVAL_P(attr); } ldap_attrs[num_attribs] = NULL; default: @@ -1680,6 +1686,12 @@ cleanup: /* Restoring previous options */ php_set_opts(ld->link, old_ldap_sizelimit, old_ldap_timelimit, old_ldap_deref, &ldap_sizelimit, &ldap_timelimit, &ldap_deref); } + if (ldap_filter) { + zend_string_release(ldap_filter); + } + if (ldap_base_dn) { + zend_string_release(ldap_base_dn); + } if (ldap_attrs != NULL) { efree(ldap_attrs); } @@ -2213,7 +2225,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) int i, j, num_attribs, num_values, msgid; size_t dn_len; int *num_berval; - zend_string *attribute, *tmpstring; + zend_string *attribute; zend_ulong index; int is_full_add=0; /* flag for full add operation so ldap_mod_add can be put back into oper, gerrit THomson */ @@ -2274,14 +2286,14 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) /* allow for arrays with one element, no allowance for arrays with none but probably not required, gerrit thomson. */ if ((num_values == 1) && (Z_TYPE_P(value) != IS_ARRAY)) { - tmpstring = zval_get_string(value); + convert_to_string(value); if (EG(exception)) { RETVAL_FALSE; goto cleanup; } ldap_mods[i]->mod_bvalues[0] = (struct berval *) emalloc (sizeof(struct berval)); - ldap_mods[i]->mod_bvalues[0]->bv_val = ZSTR_VAL(tmpstring); - ldap_mods[i]->mod_bvalues[0]->bv_len = ZSTR_LEN(tmpstring); + ldap_mods[i]->mod_bvalues[0]->bv_val = Z_STRVAL_P(value); + ldap_mods[i]->mod_bvalues[0]->bv_len = Z_STRLEN_P(value); } else { for (j = 0; j < num_values; j++) { 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) RETVAL_FALSE; goto cleanup; } - tmpstring = zval_get_string(ivalue); + convert_to_string(ivalue); if (EG(exception)) { RETVAL_FALSE; goto cleanup; } ldap_mods[i]->mod_bvalues[j] = (struct berval *) emalloc (sizeof(struct berval)); - ldap_mods[i]->mod_bvalues[j]->bv_val = ZSTR_VAL(tmpstring); - ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(tmpstring); + ldap_mods[i]->mod_bvalues[j]->bv_val = Z_STRVAL_P(ivalue); + ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(ivalue); } } ldap_mods[i]->mod_bvalues[num_values] = NULL; @@ -2823,6 +2835,7 @@ PHP_FUNCTION(ldap_modify_batch) /* fill it */ ldap_mods[i]->mod_bvalues[j]->bv_len = ZSTR_LEN(modval); ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(ZSTR_VAL(modval), ZSTR_LEN(modval)); + zend_string_release(modval); } /* NULL-terminate values */ @@ -3187,6 +3200,7 @@ PHP_FUNCTION(ldap_get_option) } RETURN_FALSE; } + zval_ptr_dtor(retval); _php_ldap_controls_to_array(ld->link, ctrls, retval, 1); } break; /* options not implemented @@ -3331,8 +3345,10 @@ PHP_FUNCTION(ldap_set_option) RETURN_FALSE; } if (ldap_set_option(ldap, option, ZSTR_VAL(val))) { + zend_string_release(val); RETURN_FALSE; } + zend_string_release(val); } break; /* options with boolean value */ case LDAP_OPT_REFERRALS: |