Fix RMR routing statistic data printout crash 66/7566/2 4.8.2
authorAlexandre Huff <alexandrehuff@utfpr.edu.br>
Mon, 17 Jan 2022 22:59:22 +0000 (19:59 -0300)
committerAlexandre Huff <alexandrehuff@utfpr.edu.br>
Fri, 11 Feb 2022 09:31:12 +0000 (06:31 -0300)
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 <alexandrehuff@utfpr.edu.br>
Change-Id: I03b0cb79a62e7fbdb1eb08c2006894fab4ebf5cd
Signed-off-by: Alexandre Huff <alexandrehuff@utfpr.edu.br>
CHANGES_CORE.txt
CMakeLists.txt
docs/rel-notes.rst
src/rmr/common/src/rt_generic_static.c
src/rmr/common/src/rtc_static.c

index 1843414..562518e 100644 (file)
@@ -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.
index 93d2733..b13880c 100644 (file)
@@ -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" )
index 8e85e60..0e09166 100644 (file)
@@ -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
 ------------------------------
 
index c2fd5f8..9a8d1fd 100644 (file)
@@ -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 ) {
index 10bc2a7..f29f65f 100644 (file)
@@ -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
                                }
                        }