diff --git a/debian/patches/series b/debian/patches/series index 16d115cac..f60d4122c 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -43,6 +43,8 @@ sipwise/lost-add-method-parameter-to-http_connect-calls.patch sipwise/usrloc-don-t-synchronize-on-destroy-for-DB_ONLY.patch sipwise/presence_offline_cleanup.patch ### active development +sipwise/db_redis_protect_length_overflow.patch +sipwise/db_redis_support_null_key_values.patch sipwise/permissions-don-t-allow-reloads-in-the-middle-of-ong.patch sipwise/permissions_consider_db_mode_when_rpc_reload.patch 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..159565a6f --- /dev/null +++ b/debian/patches/sipwise/db_redis_protect_length_overflow.patch @@ -0,0 +1,140 @@ +From: Sipwise Development Team +Date: Tue, 13 Jan 2026 09:50:54 +0100 +Subject: db_redis_protect_length_overflow + +--- + src/modules/db_redis/db_redis_mod.c | 2 ++ + src/modules/db_redis/redis_dbase.c | 7 +++---- + src/modules/db_redis/redis_table.c | 33 ++++++++++++++++++++++++++++----- + src/modules/db_redis/redis_table.h | 4 ++-- + 4 files changed, 35 insertions(+), 11 deletions(-) + +diff --git a/src/modules/db_redis/db_redis_mod.c b/src/modules/db_redis/db_redis_mod.c +index 11c7b8c..fafafbb 100644 +--- 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}, +diff --git a/src/modules/db_redis/redis_dbase.c b/src/modules/db_redis/redis_dbase.c +index b98f401..6725bf5 100644 +--- 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_pattern(km_redis_con_t *con, + 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_pattern(km_redis_con_t *con, + 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_pattern(km_redis_con_t *con, + 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; + } +diff --git a/src/modules/db_redis/redis_table.c b/src/modules/db_redis/redis_table.c +index af3700d..2100884 100644 +--- 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"); +diff --git a/src/modules/db_redis/redis_table.h b/src/modules/db_redis/redis_table.h +index 6ba4e8c..879b50c 100644 +--- 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 *con); + 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); diff --git a/debian/patches/sipwise/db_redis_support_null_key_values.patch b/debian/patches/sipwise/db_redis_support_null_key_values.patch new file mode 100644 index 000000000..cf2a487e1 --- /dev/null +++ b/debian/patches/sipwise/db_redis_support_null_key_values.patch @@ -0,0 +1,41 @@ +From: Sipwise Development Team +Date: Fri, 6 Mar 2026 10:37:29 +0100 +Subject: db_redis_support_null_key_values + +--- + src/modules/db_redis/redis_table.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/modules/db_redis/redis_table.c b/src/modules/db_redis/redis_table.c +index 2100884..09b1225 100644 +--- a/src/modules/db_redis/redis_table.c ++++ b/src/modules/db_redis/redis_table.c +@@ -32,11 +32,6 @@ 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); +@@ -56,8 +51,14 @@ int db_redis_key_add_string(redis_key_t **list, const char *entry, size_t len) + goto err; + } + +- memcpy(k->key.s, entry, len); +- k->key.s[len] = '\0'; ++ /* run memcpy only on non-NULL pointer, because in fact it may happen ++ * it comes here empty and with len = 0, this is then an implicit ++ * conversion of redis key value into the empty "" string. ++ * see `db_redis_val2str()` ++ * This is the allowed behavior, but avoid then running memcpy() on it. */ ++ if (entry && len > 0) ++ memcpy(k->key.s, entry, len); ++ k->key.s[len] = '\0'; /* at least 1 byte is already pre-allocated before */ + k->key.len = len; + + if(!*list) {