From 508a99f331354b2362503a39ec25e865ad004c96 Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: Tue, 5 Nov 2013 16:58:44 +0100 Subject: [PATCH] Ticket 47577 - crash when removing entries from cache Bug Description: when the dn of an entry in the cache was adjusted to the parent dn, for soenm time teh dn was not defined, anothe thread accessing the dn of teh chached entry could crash Fix Description: hold the cache mutex when modifyingthe dn of an entry in the cache https://fedorahosted.org/389/ticket/47577 Reviewed by: ? --- ldap/servers/slapd/back-ldbm/back-ldbm.h | 2 ++ ldap/servers/slapd/back-ldbm/cache.c | 8 ++++++++ ldap/servers/slapd/back-ldbm/id2entry.c | 2 ++ ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 2 ++ 4 files changed, 14 insertions(+) diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index 10489e3..26e081c 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -409,6 +409,8 @@ struct cache { #define CACHE_ADD(cache, p, a) cache_add((cache), (void *)(p), (void **)(a)) #define CACHE_RETURN(cache, p) cache_return((cache), (void **)(p)) #define CACHE_REMOVE(cache, p) cache_remove((cache), (void *)(p)) +#define CACHE_LOCK(cache) cache_lock((cache)) +#define CACHE_UNLOCK(cache) cache_unlock((cache)) /* various modules keep private data inside the attrinfo structure */ typedef struct dblayer_private dblayer_private; diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c index 5fa06fb..a73ae6a 100644 --- a/ldap/servers/slapd/back-ldbm/cache.c +++ b/ldap/servers/slapd/back-ldbm/cache.c @@ -1472,6 +1472,14 @@ int cache_add_tentative(struct cache *cache, struct backentry *e, { return entrycache_add_int(cache, e, ENTRY_STATE_CREATING, alt); } +void cache_lock(struct cache *cache) +{ + PR_Lock(cache->c_mutex); +} +void cache_unlock(struct cache *cache) +{ + PR_Unlock(cache->c_mutex); +} /* locks an entry so that it can be modified (you should have gotten the * entry via cache_find_*). diff --git a/ldap/servers/slapd/back-ldbm/id2entry.c b/ldap/servers/slapd/back-ldbm/id2entry.c index 281bb1b..e904ae3 100644 --- a/ldap/servers/slapd/back-ldbm/id2entry.c +++ b/ldap/servers/slapd/back-ldbm/id2entry.c @@ -167,10 +167,12 @@ id2entry_add_ext(backend *be, struct backentry *e, back_txn *txn, if (myparentdn && PL_strcmp(parentdn, myparentdn)) { Slapi_DN *sdn = slapi_entry_get_sdn(e->ep_entry); char *newdn = NULL; + CACHE_LOCK(&inst->inst_cache); slapi_sdn_done(sdn); newdn = slapi_ch_smprintf("%s,%s", myrdn, parentdn); slapi_sdn_init_dn_passin(sdn, newdn); slapi_sdn_get_ndn(sdn); /* to set ndn */ + CACHE_UNLOCK(&inst->inst_cache); } slapi_ch_free_string(&myparentdn); } diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index 7a7b7ff..937974e 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -76,6 +76,8 @@ void cache_get_stats(struct cache *cache, PRUint64 *hits, PRUint64 *tries, void cache_debug_hash(struct cache *cache, char **out); int cache_remove(struct cache *cache, void *e); void cache_return(struct cache *cache, void **bep); +void cache_lock(struct cache *cache); +void cache_unlock(struct cache *cache); struct backentry *cache_find_dn(struct cache *cache, const char *dn, unsigned long ndnlen); struct backentry *cache_find_id(struct cache *cache, ID id); struct backentry *cache_find_uuid(struct cache *cache, const char *uuid); -- 1.7.11.7