diff --git a/debian/patches/series b/debian/patches/series index d86ada50f..6ce00a453 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -45,6 +45,7 @@ sipwise/presence_offline_cleanup.patch ### active development sipwise/permissions-don-t-allow-reloads-in-the-middle-of-ong.patch sipwise/dlg_get_var_error_more_verbose_on_dlg +sipwise/db_redis_protect_length_overflow.patch ### Don't just put stuff in any order ### use gbp pq import/export tooling to help maintain patches ### diff --git a/debian/patches/sipwise/db_redis_protect_length_overflow.patch b/debian/patches/sipwise/db_redis_protect_length_overflow.patch new file mode 100644 index 000000000..f9161d6ff --- /dev/null +++ b/debian/patches/sipwise/db_redis_protect_length_overflow.patch @@ -0,0 +1,121 @@ +--- a/src/modules/db_redis/db_redis_mod.c ++++ b/src/modules/db_redis/db_redis_mod.c +@@ -42,6 +42,7 @@ MODULE_VERSION + str redis_keys = str_init(""); + str redis_schema_path = str_init(SHARE_DIR "db_redis/kamailio"); + int db_redis_verbosity = 1; ++unsigned int db_redis_max_key_len = 0; + + static int db_redis_bind_api(db_func_t *dbb); + static int mod_init(void); +@@ -60,6 +61,7 @@ static param_export_t params[] = { + {"keys", PARAM_STRING | PARAM_USE_FUNC, (void *)keys_param}, + {"schema_path", PARAM_STR, &redis_schema_path}, + {"verbosity", PARAM_INT, &db_redis_verbosity}, ++ {"max_key_length", PARAM_INT, &db_redis_max_key_len}, + #ifdef WITH_SSL + {"opt_tls", PARAM_INT, &db_redis_opt_tls}, + {"ca_path", PARAM_STRING, &db_redis_ca_path}, +--- a/src/modules/db_redis/redis_dbase.c ++++ b/src/modules/db_redis/redis_dbase.c +@@ -876,7 +876,7 @@ static int db_redis_scan_query_keys_patt + LM_ERR("Failed to add scan command to scan query\n"); + goto err; + } +- if(db_redis_key_add_string(&query_v, index_key->s, index_key->len) ++ if(db_redis_key_add_str(&query_v, index_key) + != 0) { + LM_ERR("Failed to add scan command to scan query\n"); + goto err; +@@ -891,8 +891,7 @@ static int db_redis_scan_query_keys_patt + LM_ERR("Failed to add match command to scan query\n"); + goto err; + } +- if(db_redis_key_add_string( +- &query_v, match_pattern->s, match_pattern->len) ++ if (db_redis_key_add_str(&query_v, match_pattern) + != 0) { + LM_ERR("Failed to add match pattern to scan query\n"); + goto err; +@@ -907,7 +906,7 @@ static int db_redis_scan_query_keys_patt + LM_ERR("Failed to print integer for scan query\n"); + goto err; + } +- if(db_redis_key_add_string(&query_v, match_count_str, l) != 0) { ++ if(db_redis_key_add_string(&query_v, match_count_str, (size_t)l) != 0) { + LM_ERR("Failed to add count value to scan query\n"); + goto err; + } +--- a/src/modules/db_redis/redis_table.c ++++ b/src/modules/db_redis/redis_table.c +@@ -24,14 +24,24 @@ + #include + #include + +-#include "db_redis_mod.h" +-#include "redis_connection.h" + #include "redis_table.h" + +-int db_redis_key_add_string(redis_key_t **list, const char *entry, int len) ++extern unsigned int db_redis_max_key_len; ++ ++int db_redis_key_add_string(redis_key_t **list, const char *entry, size_t len) + { + redis_key_t *k; + ++ if (!entry || !len) { ++ LM_ERR("Empty entry or zero length\n"); ++ return -1; ++ } ++ ++ if (db_redis_max_key_len > 0 && len > db_redis_max_key_len) { ++ LM_ERR("Too big length for key being added: allowed '%u' / given '%zu'\n", ++ db_redis_max_key_len, len); ++ return -1; ++ } + + k = (redis_key_t *)pkg_malloc(sizeof(redis_key_t)); + if(!k) { +@@ -69,13 +79,26 @@ err: + + int db_redis_key_add_str(redis_key_t **list, const str *entry) + { +- return db_redis_key_add_string(list, entry->s, entry->len); ++ if (entry->len < 0) ++ return -1; ++ return db_redis_key_add_string(list, entry->s, (size_t)entry->len); + } + +-int db_redis_key_prepend_string(redis_key_t **list, const char *entry, int len) ++int db_redis_key_prepend_string(redis_key_t **list, const char *entry, size_t len) + { + redis_key_t *k; + ++ if (!entry || !len) { ++ LM_ERR("Empty entry or zero length\n"); ++ return -1; ++ } ++ ++ if (db_redis_max_key_len > 0 && len > db_redis_max_key_len) { ++ LM_ERR("Too big length for key being prepended: allowed '%u' / given '%zu'\n", ++ db_redis_max_key_len, len); ++ return -1; ++ } ++ + k = (redis_key_t *)pkg_malloc(sizeof(redis_key_t)); + if(!k) { + LM_ERR("Failed to allocate memory for key list entry\n"); +--- a/src/modules/db_redis/redis_table.h ++++ b/src/modules/db_redis/redis_table.h +@@ -61,9 +61,9 @@ void db_redis_free_tables(km_redis_con_t + int db_redis_parse_schema(km_redis_con_t *con); + int db_redis_parse_keys(km_redis_con_t *con); + +-int db_redis_key_add_string(redis_key_t **list, const char *entry, int len); ++int db_redis_key_add_string(redis_key_t **list, const char *entry, size_t len); + int db_redis_key_add_str(redis_key_t **list, const str *entry); +-int db_redis_key_prepend_string(redis_key_t **list, const char *entry, int len); ++int db_redis_key_prepend_string(redis_key_t **list, const char *entry, size_t len); + int db_redis_key_list2arr(redis_key_t *list, char ***arr); + redis_key_t *db_redis_key_shift(redis_key_t **list); + void db_redis_key_free(redis_key_t **list);