sbonazzo / rpms / cyrus-sasl

Forked from rpms/cyrus-sasl 2 years ago
Clone

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

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