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

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