From 571f580206b38cc92b87c7458a42f2b1a4789830 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Mon, 8 Feb 2010 08:49:51 -0800 Subject: 548535 - memory leak in attrcrypt https://bugzilla.redhat.com/show_bug.cgi?id=548535 Description: The attrcrypt module maintains the inst_attrcrypt_state_private field in the instance structure (ldbm_instance) to store the private keys. The area and the space for the private keys are allocated in attrcrypt_init which is called from dblayer_instance_start. A backend instance could be closed and restarted multiple times (for instance, in the bulk_import, which is used by the replica initialization), but the area had no chance to be freed. This patch is adding the clean-up code. --- ldap/servers/slapd/back-ldbm/dblayer.c | 8 +++++++- ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c | 28 +++++++++++++++++++++++++- ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c index e6d13faa..b99d7e9d 100644 --- a/ldap/servers/slapd/back-ldbm/dblayer.c +++ b/ldap/servers/slapd/back-ldbm/dblayer.c @@ -1783,7 +1783,7 @@ autosize_import_cache(struct ldbminfo *li) size_t pagesize, pages, procpages, availpages; dblayer_sys_pages(&pagesize, &pages, &procpages, &availpages); - LDAPDebug(LDAP_DEBUG_ANY, "dblayer_instance_start: " + LDAPDebug(LDAP_DEBUG_ANY, "autosize_import_cache: " "pagesize: %d, pages: %d, procpages: %d\n", pagesize, pages, procpages); if (pagesize) { @@ -2470,6 +2470,12 @@ int dblayer_instance_close(backend *be) if (NULL == inst) return -1; + if (attrcrypt_cleanup_private(inst)) { + LDAPDebug(LDAP_DEBUG_ANY, + "Error: failed to clean up attrcrypt system for %s\n", + inst->inst_name, 0, 0); + } + return_value = dblayer_close_indexes(be); /* Now close id2entry if it's open */ diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c index d281506e..985b6903 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c @@ -461,7 +461,10 @@ attrcrypt_init(ldbm_instance *li) SECKEYPublicKey *public_key = NULL; LDAPDebug(LDAP_DEBUG_TRACE,"-> attrcrypt_init\n", 0, 0, 0); if (slapd_security_library_is_initialized()) { - li->inst_attrcrypt_state_private = NULL; + /* In case the backend instance is restarted, + * inst_attrcrypt_state_private in li could have memory containing + * private keys. The private data should be cleaned up first. */ + attrcrypt_cleanup_private(li); /* Get the server's private key, which is used to unwrap the stored symmetric keys */ ret = attrcrypt_fetch_private_key(&private_key); if (!ret) { @@ -515,6 +518,29 @@ int attrcrypt_check_enable_cipher(attrcrypt_cipher_entry *ace) return ret; } +/* + * This function cleans up the inst_attrcrypt_state_private in each backend + * instance. + */ +int +attrcrypt_cleanup_private(ldbm_instance *li) +{ + int i = 0; + attrcrypt_cipher_state **current = NULL; + + LDAPDebug(LDAP_DEBUG_TRACE, "-> attrcrypt_cleanup_private\n", 0, 0, 0); + if (li && li->inst_attrcrypt_state_private) { + for (current = &(li->inst_attrcrypt_state_private->acs_array[0]); + *current; current++) { + attrcrypt_cleanup(*current); + slapi_ch_free((void **)current); + } + slapi_ch_free((void **)&li->inst_attrcrypt_state_private); + } + LDAPDebug(LDAP_DEBUG_TRACE, "<- attrcrypt_cleanup_private\n", 0, 0, 0); + return 0; +} + int attrcrypt_cleanup(attrcrypt_cipher_state *acs) { diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index 008a9495..a64919c8 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -645,6 +645,7 @@ int attrcrypt_encrypt_entry(backend *be, const struct backentry *in, struct back int attrcrypt_encrypt_index_key(backend *be, struct attrinfo *ai, const struct berval *in, struct berval **out); int attrcrypt_decrypt_index_key(backend *be, struct attrinfo *ai, const struct berval *in, struct berval **out); int attrcrypt_init(ldbm_instance *li); +int attrcrypt_cleanup_private(ldbm_instance *li); /* * ldbm_usn.c -- cgit