Author: rmeggins
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4860/ldapserver/ldap/servers/slapd
Modified Files:
add.c ava.c bind.c compare.c delete.c filter.c modify.c
modrdn.c
Log Message:
Bug(s) fixed: 179135
Bug Description: memory leaks using ber_scanf when handling bad BER packets
Reviewed by: All (Thanks!)
Files:
https://bugzilla.redhat.com/bugzilla/attachment.cgi?id=123783
Branch: HEAD
Fix Description:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=179135#c0
I basically did a search through our code for all calls to ber_scanf,
ber_get_stringa, and ber_get_stringal and made sure we properly free any
arguments that may have been allocated. There was a bug in the ldapsdk
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=179135 that causes
us to free uninitialized memory when trying to clean up the result of
ber_get_stringal (or ber_scanf with 'V'). I had to initialize some
variables to NULL so that we could properly clean them up, and added
some additional clean ups that were missing. Also, in repl_extop.c, we
were calling free on an array that we should have been calling
ch_array_free on. Yet another lesson in the evils of slapi_ch_free and
disabling compiler type checks in general.
Platforms tested: Fedora Core 4
Flag Day: no
Doc impact: no
Index: add.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/add.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- add.c 19 Apr 2005 22:07:36 -0000 1.5
+++ add.c 23 Feb 2006 20:45:16 -0000 1.6
@@ -102,8 +102,9 @@
*/
/* get the name */
{
- char *dn;
+ char *dn = NULL;
if ( ber_scanf( ber, "{a", &dn ) == LBER_ERROR ) {
+ slapi_ch_free_string(&dn);
LDAPDebug( LDAP_DEBUG_ANY,
"ber_scanf failed (op=Add; params=DN)\n", 0, 0, 0 );
op_shared_log_error_access (pb, "ADD", "???", "decoding
error");
@@ -121,11 +122,13 @@
tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) ) {
char *type = NULL, *normtype = NULL;
- struct berval **vals;
+ struct berval **vals = NULL;
if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn
(slapi_entry_get_sdn_const(e)), "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
+ slapi_ch_free_string(&type);
+ ber_bvecfree( vals );
goto free_and_return;
}
@@ -134,7 +137,7 @@
op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn
(slapi_entry_get_sdn_const(e)), "null value");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL,
0, NULL );
- free( type );
+ slapi_ch_free_string(&type);
goto free_and_return;
}
@@ -144,7 +147,7 @@
PR_snprintf (ebuf, BUFSIZ, "invalid type '%s'", type);
op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn
(slapi_entry_get_sdn_const(e)), ebuf);
send_ldap_result( pb, rc, NULL, ebuf, 0, NULL );
- free( type );
+ slapi_ch_free_string(&type);
slapi_ch_free( (void**)&normtype );
ber_bvecfree( vals );
goto free_and_return;
Index: ava.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/ava.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ava.c 19 Apr 2005 22:07:36 -0000 1.4
+++ ava.c 23 Feb 2006 20:45:16 -0000 1.5
@@ -53,10 +53,12 @@
struct ava *ava
)
{
- char *type;
+ char *type = NULL;
if ( ber_scanf( ber, "{ao}", &type, &ava->ava_value )
== LBER_ERROR ) {
+ slapi_ch_free_string(&type);
+ ava_done(ava);
LDAPDebug( LDAP_DEBUG_ANY, " get_ava ber_scanf\n", 0, 0, 0 );
return( LDAP_PROTOCOL_ERROR );
}
Index: bind.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/bind.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- bind.c 19 Apr 2005 22:07:36 -0000 1.6
+++ bind.c 23 Feb 2006 20:45:16 -0000 1.7
@@ -111,7 +111,7 @@
long ber_version = -1;
int auth_response_requested = 0;
int pw_response_requested = 0;
- char *dn, *saslmech = NULL;
+ char *dn = NULL, *saslmech = NULL;
struct berval cred = {0};
Slapi_Backend *be = NULL;
unsigned long rc;
@@ -154,6 +154,7 @@
log_bind_access (pb, "???", method, version, saslmech, "decoding
error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
+ slapi_ch_free_string(&dn);
return;
}
Index: compare.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/compare.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- compare.c 19 Apr 2005 22:07:36 -0000 1.4
+++ compare.c 23 Feb 2006 20:45:16 -0000 1.5
@@ -60,13 +60,13 @@
do_compare( Slapi_PBlock *pb )
{
BerElement *ber = pb->pb_op->o_ber;
- char *dn;
- struct ava ava;
+ char *dn = NULL;
+ struct ava ava = {0};
Slapi_Backend *be = NULL;
int err;
char ebuf[ BUFSIZ ];
Slapi_DN sdn;
- Slapi_Entry *referral;
+ Slapi_Entry *referral = NULL;
char errorbuf[BUFSIZ];
LDAPDebug( LDAP_DEBUG_TRACE, "do_compare\n", 0, 0, 0 );
@@ -74,6 +74,9 @@
/* count the compare request */
PR_AtomicIncrement(g_get_global_snmp_vars()->ops_tbl.dsCompareOps);
+ /* have to init this here so we can "done" it below if we short circuit */
+ slapi_sdn_init(&sdn);
+
/*
* Parse the compare request. It looks like this:
*
@@ -86,7 +89,6 @@
* }
*/
-
if ( ber_scanf( ber, "{a{ao}}", &dn, &ava.ava_type,
&ava.ava_value ) == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_ANY,
@@ -94,7 +96,7 @@
0, 0, 0 );
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
NULL );
- return;
+ goto free_and_return;
}
/*
* in LDAPv3 there can be optional control extensions on
@@ -106,6 +108,7 @@
goto free_and_return;
}
slapi_sdn_init_dn_passin(&sdn,dn);
+ dn = NULL; /* do not free - sdn owns it now */
/* target spec is used to decide which plugins are applicable for the operation */
operation_set_target_spec (pb->pb_op, &sdn);
@@ -181,5 +184,6 @@
if (be)
slapi_be_Unlock(be);
slapi_sdn_done(&sdn);
+ slapi_ch_free_string(&dn);
ava_done( &ava );
}
Index: delete.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/delete.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- delete.c 19 Apr 2005 22:07:36 -0000 1.4
+++ delete.c 23 Feb 2006 20:45:16 -0000 1.5
@@ -66,7 +66,7 @@
{
Slapi_Operation *operation;
BerElement *ber;
- char *dn;
+ char *dn = NULL;
int err;
LDAPDebug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
@@ -89,7 +89,7 @@
op_shared_log_error_access (pb, "DEL", "???", "decoding
error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
NULL );
- return;
+ goto free_and_return;
}
/*
Index: filter.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/filter.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- filter.c 19 Apr 2005 22:07:36 -0000 1.5
+++ filter.c 23 Feb 2006 20:45:16 -0000 1.6
@@ -175,7 +175,7 @@
unsigned long len;
int err;
struct slapi_filter *f;
- char *ftmp, *type;
+ char *ftmp, *type = NULL;
LDAPDebug( LDAP_DEBUG_FILTER, "=> get_filter_internal\n", 0, 0, 0 );
@@ -293,6 +293,7 @@
case LDAP_FILTER_PRESENT:
LDAPDebug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
if ( ber_scanf( ber, "a", &type ) == LBER_ERROR ) {
+ slapi_ch_free_string(&type);
err = LDAP_PROTOCOL_ERROR;
} else {
err = LDAP_SUCCESS;
@@ -440,12 +441,13 @@
)
{
unsigned long tag, len, rc;
- char *val, *last, *type;
+ char *val, *last, *type = NULL;
char ebuf[BUFSIZ];
LDAPDebug( LDAP_DEBUG_FILTER, "=> get_substring_filter\n", 0, 0, 0 );
if ( ber_scanf( ber, "{a", &type ) == LBER_ERROR ) {
+ slapi_ch_free_string(&type);
return( LDAP_PROTOCOL_ERROR );
}
f->f_sub_type = slapi_attr_syntax_normalize( type );
@@ -460,8 +462,10 @@
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) )
{
+ val = NULL;
rc = ber_scanf( ber, "a", &val );
if ( rc == LBER_ERROR ) {
+ slapi_ch_free_string(&val);
return( LDAP_PROTOCOL_ERROR );
}
if ( val == NULL || *val == '\0' ) {
@@ -573,8 +577,9 @@
}
}
{
- char* type;
+ char* type = NULL;
if (ber_scanf( ber, "a", &type ) == LBER_ERROR) {
+ slapi_ch_free_string (&type);
rc = LDAP_PROTOCOL_ERROR;
} else {
mrf->mrf_type = slapi_attr_syntax_normalize(type);
Index: modify.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/modify.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- modify.c 25 Jan 2006 16:51:39 -0000 1.8
+++ modify.c 23 Feb 2006 20:45:16 -0000 1.9
@@ -114,7 +114,7 @@
{
Slapi_Operation *operation;
BerElement *ber;
- char *last, *type;
+ char *last, *type = NULL;
unsigned long tag, len;
LDAPMod *mod;
LDAPMod **mods;
@@ -124,7 +124,7 @@
int ignored_some_mods = 0;
int has_password_mod = 0; /* number of password mods */
char *old_pw = NULL; /* remember the old password */
- char *dn;
+ char *dn = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 );
@@ -161,6 +161,7 @@
op_shared_log_error_access (pb, "MOD", "???", "decoding
error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0,
NULL );
+ slapi_ch_free_string(&dn);
return;
}
}
@@ -186,7 +187,9 @@
op_shared_log_error_access (pb, "MOD", dn, "decoding error");
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"decoding error", 0, NULL );
+ ber_bvecfree(mod->mod_bvalues);
slapi_ch_free((void **)&mod);
+ slapi_ch_free_string(&type);
goto free_and_return;
}
mod->mod_op = long_mod_op;
Index: modrdn.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/modrdn.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- modrdn.c 19 Apr 2005 22:07:36 -0000 1.4
+++ modrdn.c 23 Feb 2006 20:45:16 -0000 1.5
@@ -66,10 +66,10 @@
{
Slapi_Operation *operation;
BerElement *ber;
- char *dn, *newsuperior = NULL;
+ char *dn = NULL, *newsuperior = NULL;
char *newrdn = NULL;
- int err, deloldrdn;
- unsigned long len;
+ int err = 0, deloldrdn = 0;
+ unsigned long len = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 );
@@ -99,7 +99,7 @@
send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
"unable to decode DN, newRDN, or deleteOldRDN parameters",
0, NULL );
- return;
+ goto free_and_return;
}
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) {