]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10604: [core] Segfault in libcrypto / dtls #resolve
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 6 Sep 2017 17:29:02 +0000 (12:29 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Wed, 6 Sep 2017 17:29:02 +0000 (12:29 -0500)
src/switch_rtp.c

index 55d1381c70983b0b7b720e5ecced48bc52905df2..8568f886f0f7303b39d94320b09b4abac1bbade3 100644 (file)
@@ -3223,6 +3223,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;
        }
 
@@ -3247,8 +3248,6 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
                }
        }
 
-
-
        return r;
 }
 
@@ -3506,26 +3505,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)) {
@@ -3580,7 +3592,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)
@@ -3591,6 +3607,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
@@ -3603,6 +3620,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");
        }
@@ -3622,7 +3641,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));
@@ -3680,17 +3699,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
@@ -3698,7 +3717,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);
@@ -3729,7 +3748,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);
@@ -3785,7 +3804,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;
 
 }
 
@@ -5723,6 +5746,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) {
@@ -5739,6 +5764,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;
@@ -6673,6 +6700,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;
 
@@ -6698,6 +6726,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);