Blame SOURCES/cyrus-sasl-2.1.26-make-client-thread-sage.patch

98b3ea
From 3d48a475054911856b736ca2720b82f529dd68cf Mon Sep 17 00:00:00 2001
98b3ea
From: Noriko Hosoi <nhosoi@redhat.com>
98b3ea
Date: Wed, 1 Oct 2014 14:20:27 -0700
98b3ea
Subject: [PATCH] Bug 1147659 - cyrus-sasl client library (client.c) is not
98b3ea
 thread safe
98b3ea
98b3ea
Description: client_dispose (lib/clinet.c) which closes a connection
98b3ea
of a sasl client frees mech_list if the head of the list differs
98b3ea
from the head of the global cmechlist->mech_list.  But there was a
98b3ea
possibility that the list appears in the middle of the global mech
98b3ea
list.  By freeing the mech, it crashed a multi-threaded sasl client.
98b3ea
98b3ea
This patch checks each mech if it is in the global mech list or not.
98b3ea
Only if it is not, the mech is freed.
98b3ea
---
98b3ea
 lib/client.c | 27 +++++++++++++++++++++++++++
98b3ea
 1 file changed, 27 insertions(+)
98b3ea
98b3ea
diff --git a/lib/client.c b/lib/client.c
98b3ea
index 31fe346..3f76483 100644
98b3ea
--- a/lib/client.c
98b3ea
+++ b/lib/client.c
98b3ea
@@ -324,6 +324,26 @@ int sasl_client_init(const sasl_callback_t *callbacks)
98b3ea
   return ret;
98b3ea
 }
98b3ea
 
98b3ea
+/*
98b3ea
+ * If mech is in cmechlist->mech_list, return 1
98b3ea
+ * Otherwise, return 0
98b3ea
+ */
98b3ea
+static int mech_is_in_cmechlist(cmechanism_t *mech)
98b3ea
+{
98b3ea
+  cmechanism_t *m = cmechlist->mech_list;
98b3ea
+  if (NULL == mech) {
98b3ea
+    return 0;
98b3ea
+  }
98b3ea
+  
98b3ea
+  while (m && mech) {
98b3ea
+    if (m == mech) {
98b3ea
+      return 1;
98b3ea
+    }
98b3ea
+    m = m->next;
98b3ea
+  }
98b3ea
+  return 0;
98b3ea
+}
98b3ea
+
98b3ea
 static void client_dispose(sasl_conn_t *pconn)
98b3ea
 {
98b3ea
   sasl_client_conn_t *c_conn=(sasl_client_conn_t *) pconn;
98b3ea
@@ -352,6 +372,13 @@ static void client_dispose(sasl_conn_t *pconn)
98b3ea
       while (m) {
98b3ea
 	  prevm = m;
98b3ea
 	  m = m->next;
98b3ea
+	  if (mech_is_in_cmechlist(prevm)) {
98b3ea
+	    /*
98b3ea
+	     * If prevm exists in the global mech_list cmechlist->mech_list,
98b3ea
+	     * we should not free it as well as the rest of the list.
98b3ea
+	     */
98b3ea
+	    break;
98b3ea
+	  }
98b3ea
 	  sasl_FREE(prevm);    
98b3ea
       }
98b3ea
   }
98b3ea
-- 
98b3ea
1.9.3
98b3ea