]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10118: [freeswitch-core] Race conditions from lack of error checking in switch_cor...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 9 Mar 2017 19:22:11 +0000 (13:22 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 9 Mar 2017 19:22:25 +0000 (13:22 -0600)
src/mod/applications/mod_dptools/mod_dptools.c
src/switch_core_media.c
src/switch_cpp.cpp
src/switch_ivr_async.c
src/switch_ivr_bridge.c
src/switch_ivr_originate.c

index 04f35b538f1fae0b9bbb179c23864f1d82390016..6daddfcdc50ba56882c8325fec8e90ce18068651 100644 (file)
@@ -3271,14 +3271,22 @@ struct camping_stake {
 static void *SWITCH_THREAD_FUNC camp_music_thread(switch_thread_t *thread, void *obj)
 {
        struct camping_stake *stake = (struct camping_stake *) obj;
-       switch_core_session_t *session = stake->session;
-       switch_channel_t *channel = switch_core_session_get_channel(stake->session);
+       switch_core_session_t *session;
+       switch_channel_t *channel;
        const char *moh = stake->moh, *greet = NULL;
        switch_input_args_t args = { 0 };
        char dbuf[2] = "";
        switch_status_t status = SWITCH_STATUS_FALSE;
        const char *stop;
 
+       session = stake->session;
+
+       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+               return NULL;
+       }
+
+       channel = switch_core_session_get_channel(stake->session);
+
        if ((stop = switch_channel_get_variable(channel, "campon_stop_key"))) {
                *dbuf = *stop;
        }
@@ -3287,8 +3295,6 @@ static void *SWITCH_THREAD_FUNC camp_music_thread(switch_thread_t *thread, void
        args.buf = dbuf;
        args.buflen = sizeof(dbuf);
 
-       switch_core_session_read_lock(session);
-
        /* don't set this to a local_stream:// or you will not be happy */
        if ((greet = switch_channel_get_variable(channel, "campon_announce_sound"))) {
                status = switch_ivr_play_file(session, NULL, greet, &args);
index 4a6f14ab215867ab62930936cc22ea179b31288a..2205fe25349433f30519310603f1b53418988af7 100644 (file)
@@ -91,6 +91,7 @@ struct media_helper {
        switch_mutex_t *file_read_mutex;
        switch_mutex_t *file_write_mutex;
        int up;
+       int ready;
 };
 
 typedef enum {
@@ -6720,8 +6721,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_audio_write_thread(swi
 static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void *obj)
 {
        struct media_helper *mh = obj;
-       switch_core_session_t *session = mh->session;
-       switch_channel_t *channel = switch_core_session_get_channel(session);
+       switch_core_session_t *session;
+       switch_channel_t *channel;
        switch_status_t status;
        switch_frame_t *read_frame = NULL;
        switch_media_handle_t *smh;
@@ -6729,10 +6730,22 @@ static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void
        unsigned char CR[] = TEXT_UNICODE_LINEFEED;
        switch_frame_t cr_frame = { 0 };
 
+
+       session = mh->session;
+       
+       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+               mh->ready = -1;
+               return NULL;
+       }
+
+       mh->ready = 1;
+
        if (!(smh = session->media_handle)) {
                return NULL;
        }
 
+       channel = switch_core_session_get_channel(session);
+
        if (switch_channel_var_true(session->channel, "fire_text_events")) {
                switch_channel_set_flag(session->channel, CF_FIRE_TEXT_EVENTS);
        }
@@ -6743,8 +6756,6 @@ static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void
        t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
        t_engine->thread_id = switch_thread_self();
 
-       switch_core_session_read_lock(session);
-
        mh->up = 1;
 
        switch_core_media_check_dtls(session, SWITCH_MEDIA_TYPE_TEXT);
@@ -6845,7 +6856,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_text_thread(switch_cor
        //switch_mutex_init(&t_engine->mh.file_write_mutex, SWITCH_MUTEX_NESTED, pool);
        //switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_TEXT], SWITCH_MUTEX_NESTED, pool);
        //switch_mutex_init(&smh->write_mutex[SWITCH_MEDIA_TYPE_TEXT], SWITCH_MUTEX_NESTED, pool);
-       switch_thread_create(&t_engine->media_thread, thd_attr, text_helper_thread, &t_engine->mh, switch_core_session_get_pool(session));
+
+       t_engine->mh.ready = 0;
+
+       if (switch_thread_create(&t_engine->media_thread, thd_attr, text_helper_thread, &t_engine->mh, 
+                                                        switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
+               while(!t_engine->mh.ready) {
+                       switch_cond_next();
+               }
+       }
 
        switch_mutex_unlock(smh->control_mutex);
        return SWITCH_STATUS_SUCCESS;
@@ -6854,8 +6873,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_text_thread(switch_cor
 static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, void *obj)
 {
        struct media_helper *mh = obj;
-       switch_core_session_t *session = mh->session;
-       switch_channel_t *channel = switch_core_session_get_channel(session);
+       switch_core_session_t *session;
+       switch_channel_t *channel;
        switch_status_t status;
        switch_frame_t *read_frame = NULL;
        switch_media_handle_t *smh;
@@ -6869,10 +6888,21 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
        int buflen = SWITCH_RTP_MAX_BUF_LEN;
        int blank_enabled = 1;
 
+       session = mh->session;
+       
+       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+               mh->ready = -1;
+               return NULL;
+       }
+
+       mh->ready = 1;
+
        if (!(smh = session->media_handle)) {
                return NULL;
        }
 
+       channel = switch_core_session_get_channel(session);
+
        switch_core_autobind_cpu();
 
        if ((var = switch_channel_get_variable(session->channel, "core_video_blank_image"))) {
@@ -6895,8 +6925,6 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
        v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
        v_engine->thread_id = switch_thread_self();
 
-       switch_core_session_read_lock(session);
-
        mh->up = 1;
        switch_mutex_lock(mh->cond_mutex);
 
@@ -7052,7 +7080,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_co
        switch_mutex_init(&v_engine->mh.file_write_mutex, SWITCH_MUTEX_NESTED, pool);
        switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool);
        switch_mutex_init(&smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool);
-       switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session));
+       v_engine->mh.ready = 0;
+
+       if (switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, 
+                                                        switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
+               while(!v_engine->mh.ready) {
+                       switch_cond_next();
+               }
+       }
 
        switch_mutex_unlock(smh->control_mutex);
        return SWITCH_STATUS_SUCCESS;
index 9cf2df36146e95e89c69dd1133c3f27678b1b942..bec23291fb418f93766b56a234bfef1ceaafbc39 100644 (file)
@@ -635,11 +635,10 @@ SWITCH_DECLARE_CONSTRUCTOR CoreSession::CoreSession(switch_core_session_t *new_s
 {
        init_vars();
 
-       if (new_session) {
+       if (new_session && switch_core_session_read_lock_hangup(new_session) == SWITCH_STATUS_SUCCESS) {
                session = new_session;
                channel = switch_core_session_get_channel(session);
                allocated = 1;
-               switch_core_session_read_lock_hangup(session);
                uuid = strdup(switch_core_session_get_uuid(session));
        }
 }
index 103effa5758bbbcf807f36243210a2d268662711..2c6ed39446e047f5899fa0b9cfa0c8e1093d28f7 100644 (file)
@@ -3990,9 +3990,10 @@ static void *SWITCH_THREAD_FUNC bcast_thread(switch_thread_t *thread, void *obj)
                return NULL;
        }
 
-       switch_core_session_read_lock(bch->session);
-       switch_ivr_broadcast(switch_core_session_get_uuid(bch->session), bch->app, bch->flags);
-       switch_core_session_rwunlock(bch->session);
+       if (switch_core_session_read_lock(bch->session) == SWITCH_STATUS_SUCCESS) {
+               switch_ivr_broadcast(switch_core_session_get_uuid(bch->session), bch->app, bch->flags);
+               switch_core_session_rwunlock(bch->session);
+       }
 
        return NULL;
 
index e229ee7a4418994ec764c594d9f7556cfd87792d..98d446ad8a96d05df562ff34e7a8e6e2bfcef1a3 100644 (file)
@@ -158,8 +158,16 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
 
        vh->up = 1;
 
-       switch_core_session_read_lock(vh->session_a);
-       switch_core_session_read_lock(vh->session_b);
+       if (switch_core_session_read_lock(vh->session_a) != SWITCH_STATUS_SUCCESS) {
+               vh->up = 0;
+               return;
+       }
+
+       if (switch_core_session_read_lock(vh->session_b) != SWITCH_STATUS_SUCCESS) {
+               vh->up = 0;
+               switch_core_session_rwunlock(vh->session_a);
+               return;
+       }
 
        switch_core_session_request_video_refresh(vh->session_a);
        switch_core_session_request_video_refresh(vh->session_b);
index 9f3f5d099f3874747aa8da5bbbef264a61aea4e1..6016809fd27eb1ec3b6c766ba159ac8411c2caf3 100644 (file)
@@ -1428,10 +1428,14 @@ static void *SWITCH_THREAD_FUNC enterprise_originate_ringback_thread(switch_thre
 {
        struct ent_originate_ringback *rb_data = (struct ent_originate_ringback *) obj;
        switch_core_session_t *session = rb_data->session;
-       switch_channel_t *channel = switch_core_session_get_channel(rb_data->session);
+       switch_channel_t *channel;
        switch_status_t status = SWITCH_STATUS_FALSE;
 
-       switch_core_session_read_lock(session);
+       if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
+               return NULL;
+       }
+
+       channel = switch_core_session_get_channel(session);
 
        while (rb_data->running && switch_channel_ready(channel)) {
                switch_ivr_parse_all_messages(session);