Blame SOURCES/0046-Ticket-48970-Serverside-sorting-crashes-the-server.patch

7c7f29
From d8399105d3b9ca281522624fdd471360b8ea59f6 Mon Sep 17 00:00:00 2001
7c7f29
From: Mark Reynolds <mreynolds@redhat.com>
7c7f29
Date: Tue, 30 Aug 2016 10:32:45 -0400
7c7f29
Subject: [PATCH 46/47] Ticket 48970 - Serverside sorting crashes the server
7c7f29
7c7f29
Bug Description:  When using a matching rule and server side sorting
7c7f29
                  the server does a double-free on the matching rule
7c7f29
                  keys which crashes the server.
7c7f29
7c7f29
Fix Description:  Set the pblock pointer to NULL after the keys are
7c7f29
                  freed.  This prevents the double free.
7c7f29
7c7f29
                  Also fixed some complier warnings/indentation.
7c7f29
7c7f29
Valgrind: passed
7c7f29
7c7f29
https://fedorahosted.org/389/ticket/48970
7c7f29
7c7f29
Reviewed by: nhosoi(Thanks!)
7c7f29
7c7f29
(cherry picked from commit 43997fa8782ca93e20595ae10e303d85e5b765f4)
7c7f29
---
7c7f29
 ldap/servers/plugins/collation/collate.c  | 14 ++++----
7c7f29
 ldap/servers/plugins/collation/orfilter.c | 55 ++++++++++++++++++-------------
7c7f29
 ldap/servers/slapd/back-ldbm/sort.c       | 12 +++----
7c7f29
 3 files changed, 43 insertions(+), 38 deletions(-)
7c7f29
7c7f29
diff --git a/ldap/servers/plugins/collation/collate.c b/ldap/servers/plugins/collation/collate.c
7c7f29
index 0480280..483a132 100644
7c7f29
--- a/ldap/servers/plugins/collation/collate.c
7c7f29
+++ b/ldap/servers/plugins/collation/collate.c
7c7f29
@@ -347,23 +347,23 @@ collation_index (indexer_t* ix, struct berval** bvec, struct berval** prefixes)
7c7f29
     return keys;
7c7f29
 }
7c7f29
 
7c7f29
+/* The destructor function for a collation-based indexer. */
7c7f29
 static void
7c7f29
 collation_indexer_destroy (indexer_t* ix)
7c7f29
-    /* The destructor function for a collation-based indexer. */
7c7f29
 {
7c7f29
     collation_indexer_t* etc = (collation_indexer_t*) ix->ix_etc;
7c7f29
     if (etc->converter) {
7c7f29
-	ucnv_close(etc->converter);
7c7f29
-	etc->converter = NULL;
7c7f29
+        ucnv_close(etc->converter);
7c7f29
+        etc->converter = NULL;
7c7f29
     }
7c7f29
 
7c7f29
     if (etc->collator) {
7c7f29
-	ucol_close(etc->collator);
7c7f29
-	etc->collator = NULL;
7c7f29
+        ucol_close(etc->collator);
7c7f29
+        etc->collator = NULL;
7c7f29
     }
7c7f29
     if (etc->ix_keys != NULL) {
7c7f29
-	ber_bvecfree (etc->ix_keys);
7c7f29
-	etc->ix_keys = NULL;
7c7f29
+        ber_bvecfree (etc->ix_keys);
7c7f29
+        etc->ix_keys = NULL;
7c7f29
     }
7c7f29
     slapi_ch_free((void**)&ix->ix_etc);
7c7f29
     ix->ix_etc = NULL; /* just for hygiene */
7c7f29
diff --git a/ldap/servers/plugins/collation/orfilter.c b/ldap/servers/plugins/collation/orfilter.c
7c7f29
index 8dc4246..084fdf6 100644
7c7f29
--- a/ldap/servers/plugins/collation/orfilter.c
7c7f29
+++ b/ldap/servers/plugins/collation/orfilter.c
7c7f29
@@ -34,7 +34,7 @@ static void
7c7f29
 indexer_free (indexer_t* ix)
7c7f29
 {
7c7f29
     if (ix->ix_destroy != NULL) {
7c7f29
-	ix->ix_destroy (ix);
7c7f29
+        ix->ix_destroy (ix);
7c7f29
     }
7c7f29
     slapi_ch_free((void**)&ix);
7c7f29
 }
7c7f29
@@ -221,23 +221,28 @@ op_filter_match (or_filter_t* or, struct berval** vals)
7c7f29
     auto indexer_t* ix = or->or_indexer;
7c7f29
     auto struct berval** v = ix->ix_index (ix, vals, NULL);
7c7f29
     if (v != NULL) for (; *v; ++v) {
7c7f29
-	auto struct berval** k = or->or_match_keys;
7c7f29
-	if (k != NULL) for (; *k; ++k) {
7c7f29
-	    switch (or->or_op) {
7c7f29
-	      case SLAPI_OP_LESS:
7c7f29
-		if (slapi_berval_cmp (*v, *k) <  0) return 0; break;
7c7f29
-	      case SLAPI_OP_LESS_OR_EQUAL:
7c7f29
-		if (slapi_berval_cmp (*v, *k) <= 0) return 0; break;
7c7f29
-	      case SLAPI_OP_EQUAL:
7c7f29
-		if (SLAPI_BERVAL_EQ  (*v, *k))      return 0; break;
7c7f29
-	      case SLAPI_OP_GREATER_OR_EQUAL:
7c7f29
-		if (slapi_berval_cmp (*v, *k) >= 0) return 0; break;
7c7f29
-	      case SLAPI_OP_GREATER:
7c7f29
-		if (slapi_berval_cmp (*v, *k) >  0) return 0; break;
7c7f29
-	      default:
7c7f29
-		break;
7c7f29
-	    }
7c7f29
-	}
7c7f29
+        auto struct berval** k = or->or_match_keys;
7c7f29
+        if (k != NULL) for (; *k; ++k) {
7c7f29
+            switch (or->or_op) {
7c7f29
+                case SLAPI_OP_LESS:
7c7f29
+                    if (slapi_berval_cmp (*v, *k) <  0) return 0;
7c7f29
+                    break;
7c7f29
+                case SLAPI_OP_LESS_OR_EQUAL:
7c7f29
+                    if (slapi_berval_cmp (*v, *k) <= 0) return 0;
7c7f29
+                    break;
7c7f29
+                case SLAPI_OP_EQUAL:
7c7f29
+                    if (SLAPI_BERVAL_EQ  (*v, *k)) return 0;
7c7f29
+                    break;
7c7f29
+                case SLAPI_OP_GREATER_OR_EQUAL:
7c7f29
+                    if (slapi_berval_cmp (*v, *k) >= 0) return 0;
7c7f29
+                    break;
7c7f29
+                case SLAPI_OP_GREATER:
7c7f29
+                    if (slapi_berval_cmp (*v, *k) >  0) return 0;
7c7f29
+                    break;
7c7f29
+                default:
7c7f29
+                    break;
7c7f29
+            }
7c7f29
+        }
7c7f29
     }
7c7f29
     return -1;
7c7f29
 }
7c7f29
@@ -570,7 +575,9 @@ op_indexer_destroy (Slapi_PBlock* pb)
7c7f29
     auto indexer_t* ix = op_indexer_get (pb);
7c7f29
     LDAPDebug (LDAP_DEBUG_FILTER, "op_indexer_destroy(%p)\n", (void*)ix, 0, 0);
7c7f29
     if (ix != NULL) {
7c7f29
-	indexer_free (ix);
7c7f29
+        indexer_free (ix);
7c7f29
+        /* The keys were freed, but we need to reset the pblock pointer */
7c7f29
+        slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, NULL);
7c7f29
     }
7c7f29
     return 0;
7c7f29
 }
7c7f29
@@ -623,10 +630,10 @@ typedef struct ss_indexer_t {
7c7f29
 static void
7c7f29
 ss_indexer_free (ss_indexer_t* ss)
7c7f29
 {
7c7f29
-	slapi_ch_free((void**)&ss->ss_oid);
7c7f29
+    slapi_ch_free_string(&ss->ss_oid);
7c7f29
     if (ss->ss_indexer != NULL) {
7c7f29
-	indexer_free (ss->ss_indexer);
7c7f29
-	ss->ss_indexer = NULL;
7c7f29
+        indexer_free (ss->ss_indexer);
7c7f29
+        ss->ss_indexer = NULL;
7c7f29
     }
7c7f29
     slapi_ch_free((void**)&ss);
7c7f29
 }
7c7f29
@@ -647,7 +654,9 @@ ss_indexer_destroy (Slapi_PBlock* pb)
7c7f29
     auto ss_indexer_t* ss = ss_indexer_get (pb);
7c7f29
     LDAPDebug (LDAP_DEBUG_FILTER, "ss_indexer_destroy(%p)\n", (void*)ss, 0, 0);
7c7f29
     if (ss) {
7c7f29
-	ss_indexer_free (ss);
7c7f29
+        ss_indexer_free(ss);
7c7f29
+        /* The keys were freed, but we need to reset the pblock pointer */
7c7f29
+        slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, NULL);
7c7f29
     }
7c7f29
 }
7c7f29
 
7c7f29
diff --git a/ldap/servers/slapd/back-ldbm/sort.c b/ldap/servers/slapd/back-ldbm/sort.c
7c7f29
index 69fe659..46f2dbd 100644
7c7f29
--- a/ldap/servers/slapd/back-ldbm/sort.c
7c7f29
+++ b/ldap/servers/slapd/back-ldbm/sort.c
7c7f29
@@ -32,15 +32,11 @@ static int print_out_sort_spec(char* buffer,sort_spec *s,int *size);
7c7f29
 
7c7f29
 static void sort_spec_thing_free(sort_spec_thing *s)
7c7f29
 {
7c7f29
-	if (NULL != s->type) {
7c7f29
-		slapi_ch_free((void **)&s->type);
7c7f29
-	}
7c7f29
-	if (NULL != s->matchrule) {
7c7f29
-		slapi_ch_free( (void**)&s->matchrule);
7c7f29
-	}
7c7f29
+	slapi_ch_free_string(&s->type);
7c7f29
+	slapi_ch_free_string(&s->matchrule);
7c7f29
 	if (NULL != s->mr_pb) {
7c7f29
 		destroy_matchrule_indexer(s->mr_pb);
7c7f29
-	    slapi_pblock_destroy (s->mr_pb);
7c7f29
+		slapi_pblock_destroy (s->mr_pb);
7c7f29
 	}
7c7f29
 	attr_done(&s->sattr);
7c7f29
 	slapi_ch_free( (void**)&s);
7c7f29
@@ -116,7 +112,7 @@ void sort_log_access(Slapi_PBlock *pb,sort_spec_thing *s,IDList *candidates)
7c7f29
 	/* Now output it */
7c7f29
 	ldbm_log_access_message(pb,buffer);
7c7f29
 	if (buffer != stack_buffer) {
7c7f29
-		slapi_ch_free( (void**)&buffer);
7c7f29
+		slapi_ch_free_string(&buffer);
7c7f29
 	}
7c7f29
 }
7c7f29
 
7c7f29
-- 
7c7f29
2.4.11
7c7f29