andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 4 months ago
Clone
Blob Blame History Raw
From bf65b45fa9d6b6ea241bb741f5aba7df392ced65 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@redhat.com>
Date: Mon, 12 Oct 2015 15:24:55 -0700
Subject: [PATCH 362/363] Ticket #48287 - Double free while adding entries
 (1.2.11 only)

Description: If a callback at SLAPI_PLUGIN_BE_TXN_*_ADD_FN fails and the
adding-entry is in a cache, the ldbm_back_add is supposed to remove the
adding-entry from the cache and free it.  The issue was fixed in 1.3.1
and newer by these tickets:
 Ticket #47808 - If be_txn plugin fails in ldbm_back_add, adding entry is double freed.
 Ticket #47815 - Add operations rejected by betxn plugins remain in cache
which were not backported to 1.2.11.

https://fedorahosted.org/389/ticket/48287

Reviewed by tbordaz@redhat.com (Thank you, Thierry!!)

(cherry picked from commit 265c6e399016ad4a46c8709d32367b9c30ea57cf)
---
 ldap/servers/slapd/add.c                |  6 ++----
 ldap/servers/slapd/back-ldbm/ldbm_add.c | 19 ++++++++++++++-----
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index 0198b1c..9f0bbc0 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -726,10 +726,8 @@ static void op_shared_add (Slapi_PBlock *pb)
 			}
 			else
 			{
-				/* restore e so we can free it below */
-				if (save_e) {
-					e = save_e;
-				}
+				/* PR_ASSERT(!save_e); save_e is supposed to be freed in the backend.  */
+				e = save_e;
 				if (rc == SLAPI_FAIL_DISKFULL)
 				{
 					operation_out_of_disk_space();
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 5069f98..b915bfe 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -108,7 +108,6 @@ ldbm_back_add( Slapi_PBlock *pb )
 	Slapi_DN parentsdn;
 	Slapi_Operation *operation;
 	int dblock_acquired= 0;
-	int is_remove_from_cache= 0;
 	int is_replicated_operation= 0;
 	int is_resurect_operation= 0;
 	int is_tombstone_operation= 0;
@@ -1173,7 +1172,20 @@ diskfull_return:
 					slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &opreturn);
 				}
 			}
-
+			if ( addingentry ) {
+				if (inst && cache_is_in_cache(&inst->inst_cache, addingentry)) {
+					CACHE_REMOVE(&inst->inst_cache, addingentry);
+					/* tell frontend not to free this entry */
+					slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL);
+				}
+				else if (!cache_has_otherref(&inst->inst_cache, addingentry))
+				{
+					if (!is_resurect_operation) { /* if resurect, tombstoneentry is dupped. */
+						backentry_clear_entry(addingentry); /* e is released in the frontend */
+					}
+				}
+				CACHE_RETURN( &inst->inst_cache, &addingentry );
+			}
 			if (!noabort) {
 				dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */
 			}
@@ -1225,9 +1237,6 @@ common_return:
 					}
 				}
 			}
-			if (is_remove_from_cache) {
-				CACHE_REMOVE(&inst->inst_cache, addingentry);
-			}
 			CACHE_RETURN( &inst->inst_cache, &addingentry );
 		}
 	}
-- 
2.4.3