ldap/servers/slapd/back-ldbm/ldbm_delete.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
New commits:
commit 1cde230fc97b87b37e8fe78028d07c2c58143bdd
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Jul 20 14:22:05 2015 -0400
Ticket 48206 - Crash during retro changelog trimming
Bug Description: If the retro changelog entry is small, its possible that
during the trimming the reto changelog entry is not in the
cache after the trim, but its tries to blindly unlock it
from the cache, which leads to a crash.
FIx Description: After we call the post op plugins and retrieve the entry
from the cache, double check that it was found. If it
is not found, do not unlock it.
https://fedorahosted.org/389/ticket/48206
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 2a8a8c8ced5849dada34ab28d79e87dd3636e413)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 619ff4a..4f97c2b 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -1286,17 +1286,24 @@ ldbm_back_delete( Slapi_PBlock *pb )
CACHE_RETURN(&inst->inst_cache, &e);
}
}
- if (cache_is_in_cache(&inst->inst_cache, e)) {
- ep_id = e->ep_id; /* Otherwise, e might have been freed. */
- CACHE_REMOVE(&inst->inst_cache, e);
- }
- cache_unlock_entry(&inst->inst_cache, e);
- CACHE_RETURN(&inst->inst_cache, &e);
- /*
- * e is unlocked and no longer in cache.
- * It could be freed at any moment.
+
+ /*
+ * e could have been replaced by cache_find_id(), recheck if it's NULL
+ * before trying to unlock it, etc.
*/
- e = NULL;
+ if (e) {
+ if (cache_is_in_cache(&inst->inst_cache, e)) {
+ ep_id = e->ep_id; /* Otherwise, e might have been freed. */
+ CACHE_REMOVE(&inst->inst_cache, e);
+ }
+ cache_unlock_entry(&inst->inst_cache, e);
+ CACHE_RETURN(&inst->inst_cache, &e);
+ /*
+ * e is unlocked and no longer in cache.
+ * It could be freed at any moment.
+ */
+ e = NULL;
+ }
if (entryrdn_get_switch() && ep_id) { /* subtree-rename: on */
/* since the op was successful, delete the tombstone dn from the dn cache */