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

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12575 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-03-11 21:22:14 +00:00
parent 2e2eea3b35
commit 0d38a7cf39
4 changed files with 28 additions and 30 deletions

View 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"/> -->

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

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

View 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)) {