|
|
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 |
|