From 2c285270cca9cc4b05bb1423da69e559cd7e7fd9 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Thu, 25 Feb 2010 09:58:35 -0800 Subject: 548115 - memory leak in schema reload https://bugzilla.redhat.com/show_bug.cgi?id=548115 Description: dse.c: 1) dse_add_entry_pb is supposed to free the given the schema entry e. Although the function never consumes the entry, it was only freeing it when the entry was added. (If it was merged or rejected, it was not freed.) schema.c: 1) when allocating a work buffer with sizedbuffer_allocate, the space for the NULL termination was not counted. 2) DSE returned from slapi_validate_schema_files must have been freed regardless of the return value. --- ldap/servers/slapd/dse.c | 13 ++++++++----- ldap/servers/slapd/schema.c | 8 +++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c index f0d124ce..e51ea7d1 100644 --- a/ldap/servers/slapd/dse.c +++ b/ldap/servers/slapd/dse.c @@ -447,6 +447,10 @@ int dse_destroy(struct dse *pdse) { int nentries = 0; + + if (NULL == pdse) { + return 0; /* no one checks this return value */ + } if (pdse->dse_rwlock) PR_RWLock_Wlock(pdse->dse_rwlock); slapi_ch_free((void **)&(pdse->dse_filename)); @@ -1144,11 +1148,10 @@ dse_add_entry_pb(struct dse* pdse, Slapi_Entry *e, Slapi_PBlock *pb) slapi_entry_free(schemacheckentry); } - /* Callers expect e (SLAPI_ADD_ENTRY) to be freed or otherwise - * consumed if the add was successful. */ - if (rc == 0) { - slapi_entry_free(e); - } + /* Callers expect e (SLAPI_ADD_ENTRY) to be freed */ + /* This function duplicates 'e' for dse_node 'n' and schemacheckentry. + * 'e' should not have been consumed */ + slapi_entry_free(e); return rc; } diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c index dadc307d..56c1b54c 100644 --- a/ldap/servers/slapd/schema.c +++ b/ldap/servers/slapd/schema.c @@ -2824,7 +2824,7 @@ read_oc_ldif ( const char *input, struct objclass **oc, char *errorbuf, /* look for the NAME */ if ( (pstart = (*keyword_strstr_fn)(nextinput, "NAME '")) != NULL ) { pstart += 6; - sizedbuffer_allocate(psbOcName,strlen(pstart)); + sizedbuffer_allocate(psbOcName,strlen(pstart)+1); if ( sscanf ( pstart, "%s", psbOcName->buffer ) > 0 ) { /* strip the trailing single quote */ if ( psbOcName->buffer[strlen(psbOcName->buffer)-1] == '\'' ) { @@ -3294,7 +3294,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf, /* look for the optional DESCription */ if ( (pStart = (*keyword_strstr_fn) ( nextinput, "DESC '")) != NULL ) { pStart += 6; - sizedbuffer_allocate(psbAttrDesc,strlen(pStart)); + sizedbuffer_allocate(psbAttrDesc,strlen(pStart)+1); strcpy ( psbAttrDesc->buffer, pStart); if ( (pEnd = strchr (psbAttrDesc->buffer, '\'' )) != NULL ){ *pEnd ='\0'; @@ -4069,6 +4069,7 @@ init_schema_dse_ext(char *schemadir, Slapi_Backend *be, return 0; /* cannot proceed; return failure */ } + *local_pschemadse = NULL; slapi_sdn_init_dn_byref(&schema,"cn=schema"); /* get schemadir if not given */ @@ -4893,8 +4894,9 @@ slapi_validate_schema_files(char *schemadir) struct dse *my_pschemadse = NULL; int rc = init_schema_dse_ext(schemadir, NULL, &my_pschemadse, DSE_SCHEMA_NO_LOAD | DSE_SCHEMA_NO_BACKEND); + dse_destroy(my_pschemadse); /* my_pschemadse was created just to + validate the schema */ if (rc) { - dse_destroy(my_pschemadse); return LDAP_SUCCESS; } else { slapi_log_error( SLAPI_LOG_FATAL, "schema_reload", -- cgit