Explorar o código

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: rmeggins
Ludwig Krispenz %!s(int64=12) %!d(string=hai) anos
pai
achega
7272dbda7f

+ 2 - 0
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;

+ 8 - 0
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_*).

+ 2 - 0
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);
                     }

+ 2 - 0
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);