]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] check_ice: sanitize second field of the candidates. Add new switch_is_uint_in_...
authorAndrey Volk <andywolk@gmail.com>
Tue, 1 Aug 2023 16:33:17 +0000 (19:33 +0300)
committerAndrey Volk <andywolk@gmail.com>
Sun, 13 Aug 2023 12:49:58 +0000 (15:49 +0300)
src/include/switch_rtp.h
src/include/switch_utils.h
src/switch_core_media.c
src/switch_utils.c
tests/unit/switch_core.c

index ca915cf77a2cbb26659fa17b320af9f44d4fedc2..dfcad5453c71ec52600f39eafe240b29f1e3d7ac 100644 (file)
@@ -106,12 +106,13 @@ typedef struct icand_s {
 } icand_t;
 
 #define MAX_CAND 50
+#define MAX_CAND_IDX_COUNT 2
 typedef struct ice_s {
 
-       icand_t cands[MAX_CAND][2];
-       int cand_idx[2];
-       int chosen[2];
-       int is_chosen[2];
+       icand_t cands[MAX_CAND][MAX_CAND_IDX_COUNT];
+       int cand_idx[MAX_CAND_IDX_COUNT];
+       int chosen[MAX_CAND_IDX_COUNT];
+       int is_chosen[MAX_CAND_IDX_COUNT];
        char *ufrag;
        char *pwd;
        char *options;
index 62f3fcd97e4f2df9f4dfc044e78a7f556373eaf5..1d33939f4c38d73358b654618b3eb3200de09dfe 100644 (file)
@@ -498,6 +498,14 @@ SWITCH_DECLARE(switch_size_t) switch_fp_read_dline(FILE *fd, char **buf, switch_
 SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
 SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
 SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
+
+/*! \brief Check if a 32 bit unsigned number is in a range.
+ * \param str string to check. Should not contain non-digit characters.
+ * \param from start of range including this number
+ * \param to end of range including this number
+ * \return true or false
+ */
+SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to);
 SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
 SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str);
 SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
index 4d11dc8b4ef7ccbb9fd11b9d708ea766a26459d1..252d94703515f7d1f6570f90c4d6193638edd556 100644 (file)
@@ -4167,10 +4167,15 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
 
                                argc = switch_split(data, ' ', fields);
 
+                               if (argc < 6 || !switch_is_uint_in_range(fields[1], 1, MAX_CAND_IDX_COUNT)) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n");
+                                       continue;
+                               }
+
                                cid = fields[1] ? atoi(fields[1]) - 1 : 0;
 
-                               if (argc < 6 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n");
+                               if (engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Too many candidates\n");
                                        continue;
                                }
 
@@ -4250,7 +4255,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
        
  relay:
        
-       for (cid = 0; cid < 2; cid++) {
+       for (cid = 0; cid < MAX_CAND_IDX_COUNT; cid++) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "Searching for %s candidate.\n", cid ? "rtcp" : "rtp");
 
                for (ai = 0; ai < engine->cand_acl_count; ai++) {
index 7561835e6963c868beb2cc3922bea94c4b261a7a..c51953f0cffc34deb4d238b8989ee6569f1cb52b 100644 (file)
@@ -1607,6 +1607,30 @@ SWITCH_DECLARE(char *) switch_separate_paren_args(char *str)
        return args;
 }
 
+SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to)
+{
+       unsigned int number;
+       const char *original_str = str;
+
+       if (str == NULL || *str == '\0' || from > to) {
+               return SWITCH_FALSE;
+       }
+
+       for (; *str != '\0'; str++) {
+               if (!isdigit(*str)) {
+                       return SWITCH_FALSE;
+               }
+       }
+
+       number = atoi(original_str);
+
+       if (number < from || number > to) {
+               return SWITCH_FALSE;
+       }
+
+       return SWITCH_TRUE;
+}
+
 SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str)
 {
        const char *p;
index 2aa0f102310868a98c2b9f87c8213c0b63c8a1b9..da93fbdef412074fe121028f1ba40bb464b91c2f 100644 (file)
@@ -95,6 +95,21 @@ FST_CORE_BEGIN("./conf")
                FST_TEST_END()
 #endif
 
+               FST_TEST_BEGIN(test_switch_is_number_in_range)
+               {
+                       fst_check_int_equals(switch_is_uint_in_range("x5", 0, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("0", 1, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("-11", -10, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("-10", -10, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("-5", -10, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("-5", -10, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("5", -10, 10), SWITCH_FALSE);
+                       fst_check_int_equals(switch_is_uint_in_range("0", 0, 10), SWITCH_TRUE);
+                       fst_check_int_equals(switch_is_uint_in_range("10", 0, 10), SWITCH_TRUE);
+                       fst_check_int_equals(switch_is_uint_in_range("11", 0, 10), SWITCH_FALSE);
+               }
+               FST_TEST_END()
+
                FST_TEST_BEGIN(test_md5)
                {
                        char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 };