andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 6456a5b75305aedc038562d3659fa942a3b2c407 Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mreynolds@redhat.com>
dc8c34
Date: Mon, 20 Jul 2015 14:22:05 -0400
dc8c34
Subject: [PATCH 352/363] Ticket 48206 - Crash during retro changelog trimming
dc8c34
dc8c34
Bug Description:  If the retro changelog entry is small, its possible that
dc8c34
                  during the trimming the reto changelog entry is not in the
dc8c34
                  cache after the trim, but its tries to blindly unlock it
dc8c34
                  from the cache, which leads to a crash.
dc8c34
dc8c34
FIx Description:  After we call the post op plugins and retrieve the entry
dc8c34
                  from the cache, double check that it was found.  If it
dc8c34
                  is not found, do not unlock it.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/48206
dc8c34
dc8c34
Reviewed by: nhosoi(Thanks!)
dc8c34
dc8c34
(cherry picked from commit 2a8a8c8ced5849dada34ab28d79e87dd3636e413)
dc8c34
dc8c34
Conflicts:
dc8c34
	ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
dc8c34
(cherry picked from commit f5552bfea4f20db3206fdf48770e86a315c9d3be)
dc8c34
---
dc8c34
 ldap/servers/slapd/back-ldbm/ldbm_delete.c | 23 +++++++++++++++++------
dc8c34
 1 file changed, 17 insertions(+), 6 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
index a03915c..47f884c 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
dc8c34
@@ -1141,13 +1141,24 @@ ldbm_back_delete( Slapi_PBlock *pb )
dc8c34
 				CACHE_RETURN(&inst->inst_cache, &e);
dc8c34
 			}
dc8c34
 		}
dc8c34
-		if (cache_is_in_cache(&inst->inst_cache, e)) {
dc8c34
-			ep_id = e->ep_id;
dc8c34
-			CACHE_REMOVE(&inst->inst_cache, e);
dc8c34
+
dc8c34
+		/*
dc8c34
+		 * e could have been replaced by cache_find_id(), recheck if it's NULL
dc8c34
+		 * before trying to unlock it, etc.
dc8c34
+		 */
dc8c34
+		if (e) {
dc8c34
+			if (cache_is_in_cache(&inst->inst_cache, e)) {
dc8c34
+				ep_id = e->ep_id; /* Otherwise, e might have been freed. */
dc8c34
+				CACHE_REMOVE(&inst->inst_cache, e);
dc8c34
+			}
dc8c34
+			cache_unlock_entry(&inst->inst_cache, e);
dc8c34
+			CACHE_RETURN(&inst->inst_cache, &e);
dc8c34
+			/*
dc8c34
+			 * e is unlocked and no longer in cache.
dc8c34
+			 * It could be freed at any moment.
dc8c34
+			 */
dc8c34
+			e = NULL;
dc8c34
 		}
dc8c34
-		cache_unlock_entry(&inst->inst_cache, e);
dc8c34
-		CACHE_RETURN(&inst->inst_cache, &e);
dc8c34
-		e = NULL;
dc8c34
 
dc8c34
 		if (entryrdn_get_switch() && ep_id) { /* subtree-rename: on */
dc8c34
 			/* since the op was successful, delete the tombstone dn from the dn cache */
dc8c34
-- 
dc8c34
2.4.3
dc8c34