]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] Fix race condition of session_table hash in switch_core_session_request_uuid() 1954/head
authorAndrey Volk <andywolk@gmail.com>
Mon, 6 Feb 2023 12:25:34 +0000 (15:25 +0300)
committerAndrey Volk <andywolk@gmail.com>
Thu, 2 Mar 2023 09:53:00 +0000 (12:53 +0300)
src/switch_core_session.c
src/switch_time.c

index 2cfdee869d40a2538816d206472f49a3cf28b6ee..44b653d9ced76edb116bb3199d586b1989f43bd4 100644 (file)
@@ -2380,11 +2380,6 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
        int32_t sps = 0;
 
 
-       if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
-               return NULL;
-       }
-
        if (direction == SWITCH_CALL_DIRECTION_INBOUND && !switch_core_ready_inbound()) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The system cannot create any inbound sessions at this time.\n");
                return NULL;
@@ -2406,6 +2401,15 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
 
        PROTECT_INTERFACE(endpoint_interface);
 
+       switch_mutex_lock(runtime.session_hash_mutex);
+       if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
+               switch_mutex_unlock(runtime.session_hash_mutex);
+               UNPROTECT_INTERFACE(endpoint_interface);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
+
+               return NULL;
+       }
+
        if (!(originate_flags & SOF_NO_LIMITS)) {
                switch_mutex_lock(runtime.throttle_mutex);
                count = session_manager.session_count;
@@ -2413,12 +2417,14 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
                switch_mutex_unlock(runtime.throttle_mutex);
 
                if (sps <= 0) {
+                       switch_mutex_unlock(runtime.session_hash_mutex);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error! %d\n", session_manager.session_count);
                        UNPROTECT_INTERFACE(endpoint_interface);
                        return NULL;
                }
 
                if ((count + 1) > session_manager.session_limit) {
+                       switch_mutex_unlock(runtime.session_hash_mutex);
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit! %d\n", session_manager.session_limit);
                        UNPROTECT_INTERFACE(endpoint_interface);
                        return NULL;
@@ -2490,7 +2496,6 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
        switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
        switch_queue_create(&session->private_event_queue_pri, SWITCH_EVENT_QUEUE_LEN, session->pool);
 
-       switch_mutex_lock(runtime.session_hash_mutex);
        switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);
        session->id = session_manager.session_id++;
        session_manager.session_count++;
index 44c1edbcce855c5926d40910693c914b03cee8d5..445e698f9b71899fa3fa1527fc1710422ae11920 100644 (file)
@@ -1243,15 +1243,17 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                        if (runtime.sps <= 0) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
                        }
+
+                       /* These two mutexes must be held in exact order: session_hash_mutex and then throttle_mutex. See switch_core_session_request_uuid() */
+                       switch_mutex_lock(runtime.session_hash_mutex);
                        switch_mutex_lock(runtime.throttle_mutex);
                        runtime.sps_last = runtime.sps_total - runtime.sps;
 
                        if (sps_interval_ticks >= 300) {
                                runtime.sps_peak_fivemin = 0;
                                sps_interval_ticks = 0;
-                               switch_mutex_lock(runtime.session_hash_mutex);
+                               /* This line is protected by runtime.session_hash_mutex */
                                runtime.sessions_peak_fivemin = session_manager.session_count;
-                               switch_mutex_unlock(runtime.session_hash_mutex);
                        }
 
                        sps_interval_ticks++;
@@ -1265,6 +1267,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
                        }
                        runtime.sps = runtime.sps_total;
                        switch_mutex_unlock(runtime.throttle_mutex);
+                       switch_mutex_unlock(runtime.session_hash_mutex);
                        tick = 0;
                }
 #ifndef DISABLE_1MS_COND