andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From bf65b45fa9d6b6ea241bb741f5aba7df392ced65 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Mon, 12 Oct 2015 15:24:55 -0700
dc8c34
Subject: [PATCH 362/363] Ticket #48287 - Double free while adding entries
dc8c34
 (1.2.11 only)
dc8c34
dc8c34
Description: If a callback at SLAPI_PLUGIN_BE_TXN_*_ADD_FN fails and the
dc8c34
adding-entry is in a cache, the ldbm_back_add is supposed to remove the
dc8c34
adding-entry from the cache and free it.  The issue was fixed in 1.3.1
dc8c34
and newer by these tickets:
dc8c34
 Ticket #47808 - If be_txn plugin fails in ldbm_back_add, adding entry is double freed.
dc8c34
 Ticket #47815 - Add operations rejected by betxn plugins remain in cache
dc8c34
which were not backported to 1.2.11.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/48287
dc8c34
dc8c34
Reviewed by tbordaz@redhat.com (Thank you, Thierry!!)
dc8c34
dc8c34
(cherry picked from commit 265c6e399016ad4a46c8709d32367b9c30ea57cf)
dc8c34
---
dc8c34
 ldap/servers/slapd/add.c                |  6 ++----
dc8c34
 ldap/servers/slapd/back-ldbm/ldbm_add.c | 19 ++++++++++++++-----
dc8c34
 2 files changed, 16 insertions(+), 9 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
dc8c34
index 0198b1c..9f0bbc0 100644
dc8c34
--- a/ldap/servers/slapd/add.c
dc8c34
+++ b/ldap/servers/slapd/add.c
dc8c34
@@ -726,10 +726,8 @@ static void op_shared_add (Slapi_PBlock *pb)
dc8c34
 			}
dc8c34
 			else
dc8c34
 			{
dc8c34
-				/* restore e so we can free it below */
dc8c34
-				if (save_e) {
dc8c34
-					e = save_e;
dc8c34
-				}
dc8c34
+				/* PR_ASSERT(!save_e); save_e is supposed to be freed in the backend.  */
dc8c34
+				e = save_e;
dc8c34
 				if (rc == SLAPI_FAIL_DISKFULL)
dc8c34
 				{
dc8c34
 					operation_out_of_disk_space();
dc8c34
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
dc8c34
index 5069f98..b915bfe 100644
dc8c34
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
dc8c34
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
dc8c34
@@ -108,7 +108,6 @@ ldbm_back_add( Slapi_PBlock *pb )
dc8c34
 	Slapi_DN parentsdn;
dc8c34
 	Slapi_Operation *operation;
dc8c34
 	int dblock_acquired= 0;
dc8c34
-	int is_remove_from_cache= 0;
dc8c34
 	int is_replicated_operation= 0;
dc8c34
 	int is_resurect_operation= 0;
dc8c34
 	int is_tombstone_operation= 0;
dc8c34
@@ -1173,7 +1172,20 @@ diskfull_return:
dc8c34
 					slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
dc8c34
 				}
dc8c34
 			}
dc8c34
-
dc8c34
+			if ( addingentry ) {
dc8c34
+				if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) {
dc8c34
+					CACHE_REMOVE(&inst->inst_cache, addingentry);
dc8c34
+					/* tell frontend not to free this entry */
dc8c34
+					slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
dc8c34
+				}
dc8c34
+				else if (!cache_has_otherref(&inst->inst_cache, addingentry))
dc8c34
+				{
dc8c34
+					if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */
dc8c34
+						backentry_clear_entry(addingentry); /* e is released in the frontend */
dc8c34
+					}
dc8c34
+				}
dc8c34
+				CACHE_RETURN( &inst->inst_cache, &addingentry );
dc8c34
+			}
dc8c34
 			if (!noabort) {
dc8c34
 				dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */
dc8c34
 			}
dc8c34
@@ -1225,9 +1237,6 @@ common_return:
dc8c34
 					}
dc8c34
 				}
dc8c34
 			}
dc8c34
-			if (is_remove_from_cache) {
dc8c34
-				CACHE_REMOVE(&inst->inst_cache, addingentry);
dc8c34
-			}
dc8c34
 			CACHE_RETURN( &inst->inst_cache, &addingentry );
dc8c34
 		}
dc8c34
 	}
dc8c34
-- 
dc8c34
2.4.3
dc8c34