mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-25 04:01:55 +00:00
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:
parent
2e2eea3b35
commit
0d38a7cf39
@ -27,7 +27,7 @@
|
|||||||
<!-- <load module="mod_ldap"/> -->
|
<!-- <load module="mod_ldap"/> -->
|
||||||
|
|
||||||
<!-- Endpoints -->
|
<!-- Endpoints -->
|
||||||
<!-- <load module="mod_dingaling"/> -->
|
<load module="mod_dingaling"/>
|
||||||
<!-- <load module="mod_iax"/> -->
|
<!-- <load module="mod_iax"/> -->
|
||||||
<!-- <load module="mod_portaudio"/> -->
|
<!-- <load module="mod_portaudio"/> -->
|
||||||
<!-- <load module="mod_alsa"/> -->
|
<!-- <load module="mod_alsa"/> -->
|
||||||
|
@ -108,6 +108,7 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
|
|||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv, *tvptr;
|
struct timeval tv, *tvptr;
|
||||||
int len;
|
int len;
|
||||||
|
char *bound;
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 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_ZERO (&fds);
|
||||||
FD_SET (sock, &fds);
|
FD_SET (sock, &fds);
|
||||||
tv.tv_sec = timeout;
|
tv.tv_sec = timeout;
|
||||||
|
|
||||||
if (timeout != -1) tvptr = &tv; else tvptr = NULL;
|
if (timeout != -1) tvptr = &tv; else tvptr = NULL;
|
||||||
if (select (sock + 1, &fds, NULL, NULL, tvptr) > 0) {
|
if (select (sock + 1, &fds, NULL, NULL, tvptr) > 0) {
|
||||||
len = recv (sock, buffer, buf_len, 0);
|
len = recv (sock, buffer, buf_len, 0);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
char *p, *e = NULL, *t = NULL;
|
char *p, *e = NULL, *t = NULL;
|
||||||
*(buffer+buf_len+1) = '\0';
|
bound = buffer + (len -1);
|
||||||
for (p = buffer; p && *p; p++) {
|
|
||||||
|
for (p = buffer; p < bound; p++) {
|
||||||
if (*p == '>') {
|
if (*p == '>') {
|
||||||
e = p;
|
e = p;
|
||||||
t = p+1;
|
t = p+1;
|
||||||
if (*t == '<') {
|
if (*t == '<') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while(t && *t) {
|
while(p < bound && t < bound) {
|
||||||
if (*t != ' ' && *t != '<') {
|
if (*t != ' ' && *t != '<') {
|
||||||
t = e = NULL;
|
t = e = NULL;
|
||||||
break;
|
break;
|
||||||
|
@ -45,17 +45,15 @@ struct stream_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_GNUTLS
|
#ifdef HAVE_GNUTLS
|
||||||
static pthread_mutex_t tls_send_mutex;
|
#include <gcrypt.h>
|
||||||
static pthread_mutex_t tls_recv_mutex;
|
GCRY_THREAD_OPTION_PTHREAD_IMPL;
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
tls_push (iksparser *prs, const char *buffer, size_t len)
|
tls_push (iksparser *prs, const char *buffer, size_t len)
|
||||||
{
|
{
|
||||||
struct stream_data *data = iks_user_data (prs);
|
struct stream_data *data = iks_user_data (prs);
|
||||||
int ret;
|
int ret;
|
||||||
pthread_mutex_lock(&tls_send_mutex);
|
|
||||||
ret = data->trans->send (data->sock, buffer, len);
|
ret = data->trans->send (data->sock, buffer, len);
|
||||||
pthread_mutex_unlock(&tls_send_mutex);
|
|
||||||
if (ret) return (size_t) -1;
|
if (ret) return (size_t) -1;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -65,9 +63,7 @@ tls_pull (iksparser *prs, char *buffer, size_t len)
|
|||||||
{
|
{
|
||||||
struct stream_data *data = iks_user_data (prs);
|
struct stream_data *data = iks_user_data (prs);
|
||||||
int ret;
|
int ret;
|
||||||
pthread_mutex_lock(&tls_recv_mutex);
|
|
||||||
ret = data->trans->recv (data->sock, buffer, len, -1);
|
ret = data->trans->recv (data->sock, buffer, len, -1);
|
||||||
pthread_mutex_unlock(&tls_recv_mutex);
|
|
||||||
if (ret == -1) return (size_t) -1;
|
if (ret == -1) return (size_t) -1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -82,6 +78,8 @@ handshake (struct stream_data *data)
|
|||||||
const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
|
const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||||
|
|
||||||
if (gnutls_global_init () != 0)
|
if (gnutls_global_init () != 0)
|
||||||
return IKS_NOMEM;
|
return IKS_NOMEM;
|
||||||
|
|
||||||
@ -99,8 +97,10 @@ handshake (struct stream_data *data)
|
|||||||
gnutls_mac_set_priority(data->sess, mac_priority);
|
gnutls_mac_set_priority(data->sess, mac_priority);
|
||||||
gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred);
|
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_push_function (data->sess, (gnutls_push_func) tls_push);
|
||||||
gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
|
gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
|
||||||
|
|
||||||
gnutls_transport_set_ptr (data->sess, data->prs);
|
gnutls_transport_set_ptr (data->sess, data->prs);
|
||||||
|
|
||||||
ret = gnutls_handshake (data->sess);
|
ret = gnutls_handshake (data->sess);
|
||||||
@ -487,10 +487,16 @@ iks_connect_fd (iksparser *prs, int fd)
|
|||||||
int
|
int
|
||||||
iks_fd (iksparser *prs)
|
iks_fd (iksparser *prs)
|
||||||
{
|
{
|
||||||
struct stream_data *data = iks_user_data (prs);
|
struct stream_data *data;
|
||||||
|
|
||||||
|
if (prs) {
|
||||||
|
data = iks_user_data (prs);
|
||||||
|
if (data) {
|
||||||
return (int) data->sock;
|
return (int) data->sock;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iks_recv (iksparser *prs, int timeout)
|
iks_recv (iksparser *prs, int timeout)
|
||||||
@ -603,24 +609,11 @@ int
|
|||||||
iks_init(void)
|
iks_init(void)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
|
|
||||||
if (pthread_mutexattr_init(&attr))
|
gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
|
if (gnutls_global_init () != 0)
|
||||||
ok = -1;
|
return IKS_NOMEM;
|
||||||
|
|
||||||
if (ok == 0 && pthread_mutex_init(&tls_send_mutex, &attr))
|
|
||||||
ok = -1;
|
|
||||||
|
|
||||||
if (ok == 0 && pthread_mutex_init(&tls_recv_mutex, &attr)) {
|
|
||||||
pthread_mutex_destroy(&tls_send_mutex);
|
|
||||||
ok = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pthread_mutexattr_destroy(&attr);
|
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
|
||||||
|
@ -1566,8 +1566,7 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
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_CONNECTED);
|
||||||
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
|
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
|
||||||
handle->state = CS_NEW;
|
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)) {
|
while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) {
|
||||||
microsleep(100);
|
microsleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iks_disconnect(handle->parser);
|
||||||
|
iks_parser_delete(handle->parser);
|
||||||
}
|
}
|
||||||
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
|
||||||
if (!ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
if (!ldl_test_flag(handle, LDL_FLAG_TLS)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user