From 4c3e34145f9b0161d09e6a94f184bbef175dc8f6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 6 Sep 2017 12:29:02 -0500 Subject: [PATCH] FS-10604: [core] Segfault in libcrypto / dtls #resolve --- src/switch_rtp.c | 59 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 1682d61c7b..e3d5a7b215 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3224,6 +3224,7 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) int pending; if (!dtls->bytes && !ready) { + switch_mutex_unlock(rtp_session->ice_mutex); return 0; } @@ -3248,8 +3249,6 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls) } } - - return r; } @@ -3467,26 +3466,39 @@ SWITCH_DECLARE(int) switch_rtp_has_dtls(void) { SWITCH_DECLARE(dtls_state_t) switch_rtp_dtls_state(switch_rtp_t *rtp_session, dtls_type_t type) { + dtls_state_t s = DS_OFF; + + switch_mutex_lock(rtp_session->ice_mutex); + if (!rtp_session || (!rtp_session->dtls && !rtp_session->rtcp_dtls)) { - return DS_OFF; + s = DS_OFF; + goto done; } if ((type == DTLS_TYPE_RTP) && rtp_session->dtls) { - return rtp_session->dtls->state; + s = rtp_session->dtls->state; + goto done; } if ((type == DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls) { - return rtp_session->rtcp_dtls->state; + s = rtp_session->rtcp_dtls->state; } - return DS_OFF; + done: + + switch_mutex_unlock(rtp_session->ice_mutex); + + return s; } SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, dtls_type_t type) { + switch_status_t status = SWITCH_STATUS_SUCCESS; + + switch_mutex_lock(rtp_session->ice_mutex); if (!rtp_session || (!rtp_session->dtls && !rtp_session->rtcp_dtls)) { - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } if ((type & DTLS_TYPE_RTP)) { @@ -3541,7 +3553,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, d } #endif - return SWITCH_STATUS_SUCCESS; + done: + + switch_mutex_unlock(rtp_session->ice_mutex); + + return status; } SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, dtls_fingerprint_t *local_fp, dtls_fingerprint_t *remote_fp, dtls_type_t type) @@ -3552,6 +3568,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d const char *kind = ""; BIO *bio; DH *dh; + switch_status_t status = SWITCH_STATUS_SUCCESS; #ifndef OPENSSL_NO_EC EC_KEY* ecdh; #endif @@ -3564,6 +3581,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d return SWITCH_STATUS_FALSE; } + switch_mutex_lock(rtp_session->ice_mutex); + if (!((type & DTLS_TYPE_RTP) || (type & DTLS_TYPE_RTCP)) || !((type & DTLS_TYPE_CLIENT) || (type & DTLS_TYPE_SERVER))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "INVALID TYPE!\n"); } @@ -3583,7 +3602,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d if (((type & DTLS_TYPE_RTP) && rtp_session->dtls) || ((type & DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "DTLS ALREADY INIT\n"); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } dtls = switch_core_alloc(rtp_session->pool, sizeof(*dtls)); @@ -3637,17 +3656,17 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d if ((ret=SSL_CTX_use_certificate_file(dtls->ssl_ctx, dtls->rsa, SSL_FILETYPE_PEM)) != 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS cert err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret)); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } if ((ret=SSL_CTX_use_PrivateKey_file(dtls->ssl_ctx, dtls->pvt, SSL_FILETYPE_PEM)) != 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS key err [%d]\n", rtp_type(rtp_session), SSL_get_error(dtls->ssl, ret)); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } if (SSL_CTX_check_private_key(dtls->ssl_ctx) == 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check key failed\n", rtp_type(rtp_session)); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } if (!zstr(dtls->ca) && switch_file_exists(dtls->ca, rtp_session->pool) == SWITCH_STATUS_SUCCESS @@ -3655,7 +3674,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check chain cert failed [%d]\n", rtp_type(rtp_session) , SSL_get_error(dtls->ssl, ret)); - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } dtls->ssl = SSL_new(dtls->ssl_ctx); @@ -3676,7 +3695,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d #ifndef OPENSSL_NO_EC ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (!ecdh) { - return SWITCH_STATUS_FALSE; + switch_goto_status(SWITCH_STATUS_FALSE, done); } SSL_set_options(dtls->ssl, SSL_OP_SINGLE_ECDH_USE); SSL_set_tmp_ecdh(dtls->ssl, ecdh); @@ -3732,7 +3751,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d rtp_session->flags[SWITCH_RTP_FLAG_VIDEO_BREAK] = 1; switch_rtp_break(rtp_session); - return SWITCH_STATUS_SUCCESS; + done: + + switch_mutex_unlock(rtp_session->ice_mutex); + + return status; } @@ -5669,6 +5692,8 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } } + switch_mutex_lock(rtp_session->ice_mutex); + if (rtp_session->dtls) { if (rtp_session->rtcp_dtls && rtp_session->rtcp_dtls != rtp_session->dtls) { @@ -5685,6 +5710,8 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } } + switch_mutex_unlock(rtp_session->ice_mutex); + if (status == SWITCH_STATUS_SUCCESS && *bytes) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { *flags &= ~SFF_RTCP; @@ -6608,6 +6635,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = 0; } + switch_mutex_lock(rtp_session->ice_mutex); if (rtp_session->rtcp_dtls) { char *b = (char *) rtp_session->rtcp_recv_msg_p; @@ -6633,6 +6661,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = 0; } } + switch_mutex_unlock(rtp_session->ice_mutex);