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

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