andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
Blob Blame History Raw
From e8b20f785742c611e6073f5e7f6723a8d2d6f264 Mon Sep 17 00:00:00 2001
From: Ludwig Krispenz <lkrispen@redhat.com>
Date: Tue, 5 Nov 2013 16:58:44 +0100
Subject: [PATCH 144/225] 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
(cherry picked from commit 7272dbda7f43974eed003cbcfc0ddd57fe433687)
(cherry picked from commit 1056a6282f246a9c396b8052d726005fe8189512)
(cherry picked from commit 00b19f3b4af662341c72fa6cfd60b5e136f1428f)
(cherry picked from commit ecc210f3ca25528f5f718680409ded0021d5604c)
(cherry picked from commit 85a99e924e16ddc69b8b2cca97550d66f4ea11e0)
---
 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 9635813..7e5a261 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -408,6 +408,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 1c81a1b..d97644f 100644
--- a/ldap/servers/slapd/back-ldbm/cache.c
+++ b/ldap/servers/slapd/back-ldbm/cache.c
@@ -1460,6 +1460,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 e278a2a..ea4523d 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 060afe2..d7b88ed 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.8.1.4