Browse Source

Merge branch 'tor-github/pr/1385'

David Goulet 6 years ago
parent
commit
ca1f18c159

+ 4 - 0
changes/bug31898

@@ -0,0 +1,4 @@
+  o Major bugfixes (embedded Tor):
+    - Avoid a possible crash when restarting Tor in embedded mode and
+      enabling a different set of publish/subscribe messages. Fixes bug
+      31898; bugfix on 0.4.1.1-alpha.

+ 1 - 0
src/lib/dispatch/.may_include

@@ -8,3 +8,4 @@ lib/dispatch/*.h
 lib/intmath/*.h
 lib/log/*.h
 lib/malloc/*.h
+lib/testsupport/*.h

+ 6 - 0
src/lib/dispatch/dispatch_cfg.h

@@ -8,6 +8,7 @@
 #define TOR_DISPATCH_CFG_H
 
 #include "lib/dispatch/msgtypes.h"
+#include "lib/testsupport/testsupport.h"
 
 /**
  * A "dispatch_cfg" is the configuration used to set up a dispatcher.
@@ -36,4 +37,9 @@ int dcfg_add_recv(dispatch_cfg_t *cfg, message_id_t msg,
 
 void dcfg_free_(dispatch_cfg_t *cfg);
 
+#ifdef DISPATCH_NEW_PRIVATE
+struct smartlist_t;
+STATIC int max_in_u16_sl(const struct smartlist_t *sl, int dflt);
+#endif
+
 #endif /* !defined(TOR_DISPATCH_CFG_H) */

+ 7 - 5
src/lib/dispatch/dispatch_new.c

@@ -9,6 +9,7 @@
  * \brief Code to construct a dispatch_t from a dispatch_cfg_t.
  **/
 
+#define DISPATCH_NEW_PRIVATE
 #define DISPATCH_PRIVATE
 #include "orconfig.h"
 
@@ -26,14 +27,14 @@
 
 /** Given a smartlist full of (possibly NULL) pointers to uint16_t values,
  * return the largest value, or dflt if the list is empty. */
-static int
-max_in_sl(const smartlist_t *sl, int dflt)
+STATIC int
+max_in_u16_sl(const smartlist_t *sl, int dflt)
 {
   uint16_t *maxptr = NULL;
   SMARTLIST_FOREACH_BEGIN(sl, uint16_t *, u) {
     if (!maxptr)
       maxptr = u;
-    else if (*u > *maxptr)
+    else if (u && *u > *maxptr)
       maxptr = u;
   } SMARTLIST_FOREACH_END(u);
 
@@ -118,11 +119,12 @@ dispatch_new(const dispatch_cfg_t *cfg)
                             smartlist_len(cfg->recv_by_msg)) + 1;
 
   /* Any channel that any message has counts towards the number of channels. */
-  const size_t n_chans = (size_t) MAX(1, max_in_sl(cfg->chan_by_msg,0)) + 1;
+  const size_t n_chans = (size_t)
+    MAX(1, max_in_u16_sl(cfg->chan_by_msg,0)) + 1;
 
   /* Any type that a message has, or that has functions, counts towards
    * the number of types. */
-  const size_t n_types = (size_t) MAX(max_in_sl(cfg->type_by_msg,0),
+  const size_t n_types = (size_t) MAX(max_in_u16_sl(cfg->type_by_msg,0),
                                       smartlist_len(cfg->fns_by_type)) + 1;
 
   d->n_msgs = n_msgs;

+ 29 - 0
src/test/test_dispatch.c

@@ -1,6 +1,7 @@
 /* Copyright (c) 2018, The Tor Project, Inc. */
 /* See LICENSE for licensing information */
 
+#define DISPATCH_NEW_PRIVATE
 #define DISPATCH_PRIVATE
 
 #include "test/test.h"
@@ -19,6 +20,33 @@
 
 static dispatch_t *dispatcher_in_use=NULL;
 
+static void
+test_dispatch_max_in_u16_sl(void *arg)
+{
+  (void)arg;
+  smartlist_t *sl = smartlist_new();
+  uint16_t nums[] = { 10, 20, 30 };
+  tt_int_op(-1, OP_EQ, max_in_u16_sl(sl, -1));
+
+  smartlist_add(sl, NULL);
+  tt_int_op(-1, OP_EQ, max_in_u16_sl(sl, -1));
+
+  smartlist_add(sl, &nums[1]);
+  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
+
+  smartlist_add(sl, &nums[0]);
+  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
+
+  smartlist_add(sl, NULL);
+  tt_int_op(20, OP_EQ, max_in_u16_sl(sl, -1));
+
+  smartlist_add(sl, &nums[2]);
+  tt_int_op(30, OP_EQ, max_in_u16_sl(sl, -1));
+
+ done:
+  smartlist_free(sl);
+}
+
 /* Construct an empty dispatch_t. */
 static void
 test_dispatch_empty(void *arg)
@@ -240,6 +268,7 @@ test_dispatch_bad_type_setup(void *arg)
   { #name, test_dispatch_ ## name, TT_FORK, NULL, NULL }
 
 struct testcase_t dispatch_tests[] = {
+  T(max_in_u16_sl),
   T(empty),
   T(simple),
   T(no_recipient),