]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
hijack gcrypt init call to fix threadsafe race in dingaling and fix buffer overrun...
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 11 Mar 2009 21:22:14 +0000 (21:22 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 11 Mar 2009 21:22:14 +0000 (21:22 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12575 d0543943-73ff-0310-b7d9-9358b9ac24b2

conf/autoload_configs/modules.conf.xml
libs/iksemel/src/io-posix.c
libs/iksemel/src/stream.c
libs/libdingaling/src/libdingaling.c

index 083d2d386689f17f2225575cb3b6486a7beccd59..4c5445f16e7914fdd972e458226ad6f21fa34b2c 100644 (file)
@@ -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"/> -->
index 6ba76b2090f930cff1e2032c6f512a8aa455a84c..18494a1b9640eeb58b743c426e876133ab58adf1 100644 (file)
@@ -108,6 +108,7 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
        fd_set fds;
        struct timeval tv, *tvptr;
        int len;
+       char *bound;
 
        tv.tv_sec = 0;
        tv.tv_usec = 0;
@@ -115,20 +116,22 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
        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;
index edbcf3047fff899f93091d84aa296f62b6456a38..c4e86a756d4a3a0800c7a8ccf4a7b71dcc980d9d 100644 (file)
@@ -45,17 +45,15 @@ struct stream_data {
 };
 
 #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 @@ tls_pull (iksparser *prs, char *buffer, size_t len)
 {
        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 @@ handshake (struct stream_data *data)
        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 @@ handshake (struct stream_data *data)
        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 @@ iks_connect_fd (iksparser *prs, int fd)
 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 @@ int
 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;
 
index 1b4f4bcca24d94602bf51a09fcc829b98337a342..8999f650919c1f686904ccda9e59651b9d70b5e5 100644 (file)
@@ -1566,8 +1566,7 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
                }
 
        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 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
                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)) {