From 817516b6d7d3ffd874192c3a5342ead4c5da498b Mon Sep 17 00:00:00 2001 From: Alexandre Huff Date: Mon, 17 Jan 2022 19:59:22 -0300 Subject: [PATCH] Fix RMR routing statistic data printout crash If a routing table update happens while traversing entries to print routing statistics, then it will cause RMR to crash. This crash is generated due to an unsafe reference used to print the rt statistics. This change fixes this routing statistic printout crash. This change also fixes a related problem of read-access to ref count in routing table that is not protected by a mutex. Issue-ID: RIC-872 Signed-off-by: Alexandre Huff Change-Id: I03b0cb79a62e7fbdb1eb08c2006894fab4ebf5cd Signed-off-by: Alexandre Huff --- CHANGES_CORE.txt | 3 +++ CMakeLists.txt | 2 +- docs/rel-notes.rst | 7 +++++++ src/rmr/common/src/rt_generic_static.c | 12 +++++++++++- src/rmr/common/src/rtc_static.c | 10 ++++++++-- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGES_CORE.txt b/CHANGES_CORE.txt index 1843414..562518e 100644 --- a/CHANGES_CORE.txt +++ b/CHANGES_CORE.txt @@ -5,6 +5,9 @@ # API and build change and fix summaries. Doc corrections # and/or changes are not mentioned here; see the commit messages. +2022 January 17; version 4.8.2 + Fixes routing statistics printout crash (RIC-872). + 2022 January 7; version 4.8.1 Re-enables RMR libary's module tests (RIC-861). Creates a new unit test for the debugging rmr rx queue API. diff --git a/CMakeLists.txt b/CMakeLists.txt index 93d2733..b13880c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ cmake_minimum_required( VERSION 3.5 ) set( major_version "4" ) # should be automatically populated from git tag later, but until CI process sets a tag we use this set( minor_version "8" ) -set( patch_level "1" ) +set( patch_level "2" ) set( install_root "${CMAKE_INSTALL_PREFIX}" ) set( install_inc "include/rmr" ) diff --git a/docs/rel-notes.rst b/docs/rel-notes.rst index 8e85e60..0e09166 100644 --- a/docs/rel-notes.rst +++ b/docs/rel-notes.rst @@ -22,6 +22,13 @@ the need to leap frog versions ceased, and beginning with version 4.0.0, the RMR versions should no longer skip. +2022 January 17; version 4.8.2 +------------------------------ + +Fixes routing statistics printout crash (RIC-872). + + + 2022 January 7; version 4.8.1 ------------------------------ diff --git a/src/rmr/common/src/rt_generic_static.c b/src/rmr/common/src/rt_generic_static.c index c2fd5f8..9a8d1fd 100644 --- a/src/rmr/common/src/rt_generic_static.c +++ b/src/rmr/common/src/rt_generic_static.c @@ -1502,6 +1502,7 @@ static route_table_t* uta_rt_clone( uta_ctx_t* ctx, route_table_t* srt, route_ta */ static route_table_t* prep_new_rt( uta_ctx_t* ctx, int all ) { int counter = 0; + int ref_count; route_table_t* rt; if( ctx == NULL ) { @@ -1510,13 +1511,22 @@ static route_table_t* prep_new_rt( uta_ctx_t* ctx, int all ) { if( (rt = ctx->old_rtable) != NULL ) { ctx->old_rtable = NULL; - while( rt->ref_count > 0 ) { // wait for all who are using to stop + + pthread_mutex_lock( ctx->rtgate ); + ref_count = rt->ref_count; + pthread_mutex_unlock( ctx->rtgate ); + + while( ref_count > 0 ) { // wait for all who are using to stop if( counter++ > 1000 ) { rmr_vlog( RMR_VL_WARN, "rt_prep_newrt: internal mishap, ref count on table seems wedged" ); break; } usleep( 1000 ); // small sleep to yield the processer if that is needed + + pthread_mutex_lock( ctx->rtgate ); + ref_count = rt->ref_count; + pthread_mutex_unlock( ctx->rtgate ); } if( rt->hash != NULL ) { diff --git a/src/rmr/common/src/rtc_static.c b/src/rmr/common/src/rtc_static.c index 10bc2a7..f29f65f 100644 --- a/src/rmr/common/src/rtc_static.c +++ b/src/rmr/common/src/rtc_static.c @@ -268,6 +268,7 @@ static void* rtc( void* vctx ) { uta_ctx_t* ctx; // context user has -- where we pin the route table uta_ctx_t* pvt_cx; // private context for session with rtg rmr_mbuf_t* msg = NULL; // message from rtg + route_table_t* rt; // the routing table that will be traversed to print statistics char* my_port; // the port number that we will listen on (4561 has been the default for this) char* rtg_addr; // host:port address of route table generator (route manager) char* daddr; // duplicated rtg address string to parse/trash @@ -385,7 +386,9 @@ static void* rtc( void* vctx ) { count_delay = 300; } if( vlevel >= 0 ) { // allow it to be forced off with -n in verbose file - rt_epcounts( ctx->rtable, ctx->my_name ); + rt = get_rt( ctx ); // get active route table and up ref count + rt_epcounts( rt, ctx->my_name ); + release_rt( ctx, rt ); // dec safely the ref counter } } @@ -464,6 +467,7 @@ static void* raw_rtc( void* vctx ) { uta_ctx_t* ctx; // context user has -- where we pin the route table uta_ctx_t* pvt_cx; // private context for session with rtg rmr_mbuf_t* msg = NULL; // message from rtg + route_table_t* rt; // the routing table that will be traversed to print statistics char* payload; // payload in the message size_t mlen; char* port; // a port number we listen/connect to @@ -582,7 +586,9 @@ static void* raw_rtc( void* vctx ) { if( blabber > bump_freq ) { count_delay = 300; } - rt_epcounts( ctx->rtable, ctx->my_name ); + rt = get_rt( ctx ); // get active route table and up ref count + rt_epcounts( rt, ctx->my_name ); + release_rt( ctx, rt ); // dec safely the ref counter } } -- 2.16.6