From 41cb540c1304bfa11a8675fcb26a178301b2820b Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Thu, 5 Nov 2020 11:22:35 +0100 Subject: [PATCH] TT#99150 permissions: basic safety for concurent rpc reload * add reload_delta parameter Change-Id: I6490ea25b2a00f793caa214f7b007a46751a7159 --- debian/patches/series | 3 + ...rmissions-add-reload_delta-parameter.patch | 73 ++++++++++++ ...asic-safety-for-concurent-rpc-reload.patch | 109 ++++++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 debian/patches/upstream/permissions-add-reload_delta-parameter.patch create mode 100644 debian/patches/upstream/permissions-basic-safety-for-concurent-rpc-reload.patch diff --git a/debian/patches/series b/debian/patches/series index 6ac972313..8523a2764 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -37,6 +37,9 @@ upstream/0002-Revert-tls-added-define-condition-on-version-functio.patch upstream/0003-Revert-tls-support-compilation-without-deprecated-Op.patch upstream/pv_headers-fix-x_hdr-index-on-get.patch upstream/ndb_redis-set-message-level-to-debug-on-exec.patch +# upstream master (5.5) +upstream/permissions-basic-safety-for-concurent-rpc-reload.patch +upstream/permissions-add-reload_delta-parameter.patch ### relevant for upstream sipwise/pua_dialoginfo-refresh_pubruri_avps_flag.patch sipwise/pua_dialoginfo-local_identity_dlg_var.patch diff --git a/debian/patches/upstream/permissions-add-reload_delta-parameter.patch b/debian/patches/upstream/permissions-add-reload_delta-parameter.patch new file mode 100644 index 000000000..a20032539 --- /dev/null +++ b/debian/patches/upstream/permissions-add-reload_delta-parameter.patch @@ -0,0 +1,73 @@ +From 01fa7503433f4e23dea156e1034a87bbb49a4a1d Mon Sep 17 00:00:00 2001 +From: Victor Seva +Date: Thu, 5 Nov 2020 12:12:38 +0100 +Subject: [PATCH] permissions: add reload_delta parameter + +- make the rate limit of maximum allowed RPC reload configurable +using the new 'reload_delta' paramenter. +--- + src/modules/permissions/permissions.c | 4 ++++ + src/modules/permissions/permissions.h | 1 + + src/modules/permissions/rpc.c | 8 +++++--- + 3 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/modules/permissions/permissions.c b/src/modules/permissions/permissions.c +index 7e447d14d2..7dd6d981c6 100644 +--- a/src/modules/permissions/permissions.c ++++ b/src/modules/permissions/permissions.c +@@ -60,6 +60,7 @@ static char* perm_deny_suffix = ".deny"; + + /* for allow_trusted and allow_address function */ + str perm_db_url = {NULL, 0}; /* Don't connect to the database by default */ ++int perm_reload_delta = 5; + + /* for allow_trusted function */ + int perm_db_mode = DISABLE_CACHE; /* Database usage mode: 0=no cache, 1=cache */ +@@ -594,6 +595,9 @@ static int mod_init(void) + } + *perm_rpc_reload_time = 0; + ++ if(perm_reload_delta < 0) ++ perm_reload_delta = 5; ++ + if(permissions_init_rpc()!=0) { + LM_ERR("failed to register RPC commands\n"); + return -1; +diff --git a/src/modules/permissions/permissions.h b/src/modules/permissions/permissions.h +index c094185626..2a417ffd58 100644 +--- a/src/modules/permissions/permissions.h ++++ b/src/modules/permissions/permissions.h +@@ -59,6 +59,7 @@ extern str perm_ip_addr_col; /* Name of ip address column */ + extern str perm_mask_col; /* Name of mask column */ + extern str perm_port_col; /* Name of port column */ + extern int perm_peer_tag_mode; /* Matching mode */ ++extern int perm_reload_delta; /* seconds between RPC reloads */ + + /* backends to be loaded */ + #define PERM_LOAD_ADDRESSDB (1<<0) +diff --git a/src/modules/permissions/rpc.c b/src/modules/permissions/rpc.c +index b6a6f9a420..cff9523406 100644 +--- a/src/modules/permissions/rpc.c ++++ b/src/modules/permissions/rpc.c +@@ -30,13 +30,15 @@ + #include "permissions.h" + + +-int rpc_check_reload(rpc_t* rpc, void* ctx) { +- if(perm_rpc_reload_time==NULL) { ++int rpc_check_reload(rpc_t *rpc, void *ctx) ++{ ++ if(perm_rpc_reload_time == NULL) { + LM_ERR("not ready for reload\n"); + rpc->fault(ctx, 500, "Not ready for reload"); + return -1; + } +- if(*perm_rpc_reload_time!=0 && *perm_rpc_reload_time > time(NULL) - 5) { ++ if(*perm_rpc_reload_time != 0 ++ && *perm_rpc_reload_time > time(NULL) - perm_reload_delta) { + LM_ERR("ongoing reload\n"); + rpc->fault(ctx, 500, "ongoing reload"); + return -1; +-- +2.20.1 + diff --git a/debian/patches/upstream/permissions-basic-safety-for-concurent-rpc-reload.patch b/debian/patches/upstream/permissions-basic-safety-for-concurent-rpc-reload.patch new file mode 100644 index 000000000..772a8b317 --- /dev/null +++ b/debian/patches/upstream/permissions-basic-safety-for-concurent-rpc-reload.patch @@ -0,0 +1,109 @@ +From: Victor Seva +Date: Thu, 5 Nov 2020 11:04:48 +0100 +Subject: permissions: basic safety for concurent rpc reload + +* same logic as 99d5da8d595961063249f871a5d150474fa6f317 +--- + src/modules/permissions/permissions.c | 14 +++++++++++++- + src/modules/permissions/permissions.h | 1 + + src/modules/permissions/rpc.c | 25 +++++++++++++++++++++++++ + 3 files changed, 39 insertions(+), 1 deletion(-) + +diff --git a/src/modules/permissions/permissions.c b/src/modules/permissions/permissions.c +index 18cf398..6b45619 100644 +--- a/src/modules/permissions/permissions.c ++++ b/src/modules/permissions/permissions.c +@@ -88,7 +88,7 @@ str perm_address_file = STR_NULL; /* Full path to file with address records + */ + static int perm_check_all_branches = 1; + +- ++time_t *perm_rpc_reload_time = NULL; + int _perm_max_subnets = 512; + + int _perm_load_backends = 0xFFFF; +@@ -587,6 +587,13 @@ static int mod_init(void) + return -1; + } + ++ perm_rpc_reload_time = shm_malloc(sizeof(time_t)); ++ if(perm_rpc_reload_time == NULL) { ++ SHM_MEM_ERROR; ++ return -1; ++ } ++ *perm_rpc_reload_time = 0; ++ + if(permissions_init_rpc()!=0) { + LM_ERR("failed to register RPC commands\n"); + return -1; +@@ -674,6 +681,11 @@ static void mod_exit(void) + { + int i; + ++ if(perm_rpc_reload_time!=NULL) { ++ shm_free(perm_rpc_reload_time); ++ perm_rpc_reload_time = 0; ++ } ++ + for(i = 0; i < perm_rules_num; i++) { + if(perm_allow[i].rules) free_rule(perm_allow[i].rules); + if(perm_allow[i].filename) pkg_free(perm_allow[i].filename); +diff --git a/src/modules/permissions/permissions.h b/src/modules/permissions/permissions.h +index 785d6c9..c094185 100644 +--- a/src/modules/permissions/permissions.h ++++ b/src/modules/permissions/permissions.h +@@ -66,6 +66,7 @@ extern int perm_peer_tag_mode; /* Matching mode */ + #define PERM_LOAD_ALLOWFILE (1<<2) + #define PERM_LOAD_DENYFILE (1<<3) + extern int _perm_load_backends; /* */ ++extern time_t *perm_rpc_reload_time; + + typedef struct int_or_pvar { + unsigned int i; +diff --git a/src/modules/permissions/rpc.c b/src/modules/permissions/rpc.c +index 844cdec..b6a6f9a 100644 +--- a/src/modules/permissions/rpc.c ++++ b/src/modules/permissions/rpc.c +@@ -30,10 +30,30 @@ + #include "permissions.h" + + ++int rpc_check_reload(rpc_t* rpc, void* ctx) { ++ if(perm_rpc_reload_time==NULL) { ++ LM_ERR("not ready for reload\n"); ++ rpc->fault(ctx, 500, "Not ready for reload"); ++ return -1; ++ } ++ if(*perm_rpc_reload_time!=0 && *perm_rpc_reload_time > time(NULL) - 5) { ++ LM_ERR("ongoing reload\n"); ++ rpc->fault(ctx, 500, "ongoing reload"); ++ return -1; ++ } ++ *perm_rpc_reload_time = time(NULL); ++ return 0; ++} ++ + /*! \brief + * RPC function to reload trusted table + */ + void rpc_trusted_reload(rpc_t* rpc, void* c) { ++ ++ if(rpc_check_reload(rpc, c) < 0) { ++ return; ++ } ++ + if (reload_trusted_table_cmd () != 1) { + rpc->fault(c, 500, "Reload failed."); + return; +@@ -67,6 +87,11 @@ void rpc_trusted_dump(rpc_t* rpc, void* c) { + * RPC function to reload address table + */ + void rpc_address_reload(rpc_t* rpc, void* c) { ++ ++ if(rpc_check_reload(rpc, c) < 0) { ++ return; ++ } ++ + if (reload_address_table_cmd () != 1) { + rpc->fault(c, 500, "Reload failed."); + return;