[Freeswitch-svn] [commit] r12575 - in freeswitch/trunk: conf/autoload_configs libs/iksemel/src libs/libdingaling/src

FreeSWITCH SVN anthm at freeswitch.org
Wed Mar 11 14:22:14 PDT 2009


Author: anthm
Date: Wed Mar 11 16:22:14 2009
New Revision: 12575

Log:
hijack gcrypt init call to fix threadsafe race in dingaling and fix buffer overrun in iksemel

Modified:
   freeswitch/trunk/conf/autoload_configs/modules.conf.xml
   freeswitch/trunk/libs/iksemel/src/io-posix.c
   freeswitch/trunk/libs/iksemel/src/stream.c
   freeswitch/trunk/libs/libdingaling/src/libdingaling.c

Modified: freeswitch/trunk/conf/autoload_configs/modules.conf.xml
==============================================================================
--- freeswitch/trunk/conf/autoload_configs/modules.conf.xml	(original)
+++ freeswitch/trunk/conf/autoload_configs/modules.conf.xml	Wed Mar 11 16:22:14 2009
@@ -27,7 +27,7 @@
     <!-- <load module="mod_ldap"/> -->
 
     <!-- Endpoints -->
-    <!-- <load module="mod_dingaling"/> -->
+    <load module="mod_dingaling"/>
     <!-- <load module="mod_iax"/> -->
     <!-- <load module="mod_portaudio"/> -->
     <!-- <load module="mod_alsa"/> -->

Modified: freeswitch/trunk/libs/iksemel/src/io-posix.c
==============================================================================
--- freeswitch/trunk/libs/iksemel/src/io-posix.c	(original)
+++ freeswitch/trunk/libs/iksemel/src/io-posix.c	Wed Mar 11 16:22:14 2009
@@ -108,6 +108,7 @@
 	fd_set fds;
 	struct timeval tv, *tvptr;
 	int len;
+	char *bound;
 
 	tv.tv_sec = 0;
 	tv.tv_usec = 0;
@@ -115,20 +116,22 @@
 	FD_ZERO (&fds);
 	FD_SET (sock, &fds);
 	tv.tv_sec = timeout;
+
 	if (timeout != -1) tvptr = &tv; else tvptr = NULL;
 	if (select (sock + 1, &fds, NULL, NULL, tvptr) > 0) {
 		len = recv (sock, buffer, buf_len, 0);
 		if (len > 0) {
 			char *p, *e = NULL, *t = NULL;
-			*(buffer+buf_len+1) = '\0';
-			for (p = buffer; p && *p; p++) {
+			bound = buffer + (len -1);
+
+			for (p = buffer; p < bound; p++) {
 				if (*p == '>') {
 					e = p;
 					t = p+1;
 					if (*t == '<') {
 						continue;
 					}
-					while(t && *t) {
+					while(p < bound && t < bound) {
 						if (*t != ' ' && *t != '<') {
 							t = e = NULL;
 							break;

Modified: freeswitch/trunk/libs/iksemel/src/stream.c
==============================================================================
--- freeswitch/trunk/libs/iksemel/src/stream.c	(original)
+++ freeswitch/trunk/libs/iksemel/src/stream.c	Wed Mar 11 16:22:14 2009
@@ -45,17 +45,15 @@
 };
 
 #ifdef HAVE_GNUTLS
-static pthread_mutex_t tls_send_mutex;
-static pthread_mutex_t tls_recv_mutex;
+#include <gcrypt.h>
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
 
 static size_t
 tls_push (iksparser *prs, const char *buffer, size_t len)
 {
 	struct stream_data *data = iks_user_data (prs);
 	int ret;
-	pthread_mutex_lock(&tls_send_mutex);
 	ret = data->trans->send (data->sock, buffer, len);
-	pthread_mutex_unlock(&tls_send_mutex);
 	if (ret) return (size_t) -1;
 	return len;
 }
@@ -65,9 +63,7 @@
 {
 	struct stream_data *data = iks_user_data (prs);
 	int ret;
-	pthread_mutex_lock(&tls_recv_mutex);
 	ret = data->trans->recv (data->sock, buffer, len, -1);
-	pthread_mutex_unlock(&tls_recv_mutex);
 	if (ret == -1) return (size_t) -1;
 	return ret;
 }
@@ -82,6 +78,8 @@
 	const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
 	int ret;
 
+	gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+
 	if (gnutls_global_init () != 0)
 		return IKS_NOMEM;
 
@@ -99,8 +97,10 @@
 	gnutls_mac_set_priority(data->sess, mac_priority);
 	gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred);
 
+
 	gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push);
 	gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
+	
 	gnutls_transport_set_ptr (data->sess, data->prs);
 
 	ret = gnutls_handshake (data->sess);
@@ -487,9 +487,15 @@
 int
 iks_fd (iksparser *prs)
 {
-	struct stream_data *data = iks_user_data (prs);
+	struct stream_data *data;
 
-	return (int) data->sock;
+	if (prs) {
+		data = iks_user_data (prs);
+		if (data) {
+			return (int) data->sock;
+		}
+	}
+	return -1;
 }
 
 int
@@ -603,24 +609,11 @@
 iks_init(void)
 {
 	int ok = 0;
-	pthread_mutexattr_t attr;
-
-	if (pthread_mutexattr_init(&attr))
-		return -1;
-	
-	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
-		ok = -1;
 	
-	if (ok == 0 && pthread_mutex_init(&tls_send_mutex, &attr))
-		ok = -1;
+	gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
 
-	if (ok == 0 && pthread_mutex_init(&tls_recv_mutex, &attr)) {
-		pthread_mutex_destroy(&tls_send_mutex);
-		ok = -1;
-	}
-	
-
-	pthread_mutexattr_destroy(&attr);
+	if (gnutls_global_init () != 0)
+		return IKS_NOMEM;
 
 	return ok;
 

Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.c	(original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.c	Wed Mar 11 16:22:14 2009
@@ -1566,8 +1566,7 @@
 		}
 
 	fail:
-		iks_disconnect(handle->parser);
-		iks_parser_delete(handle->parser);
+		
 		ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED);
 		ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
 		handle->state = CS_NEW;
@@ -1575,6 +1574,9 @@
 		while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) {
 			microsleep(100);
 		}
+
+		iks_disconnect(handle->parser);
+		iks_parser_delete(handle->parser);
 	}
 	ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
 	if (!ldl_test_flag(handle, LDL_FLAG_TLS)) {



More information about the Freeswitch-svn mailing list