summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2019-10-02 14:15:31 -0400
committerDavid Goulet <dgoulet@torproject.org>2019-10-02 14:15:31 -0400
commitca1f18c159fe2c46b32daf86334689afe2db4f94 (patch)
tree80b264353ce19545d1b6a525582c39321c4bfe4a
parent014abf86e5a6484d23f72bb6959d78e379d90206 (diff)
parent2b825a1a2e6e79fa71b0e038241d2107aaf30d4b (diff)
downloadtor-ca1f18c159fe2c46b32daf86334689afe2db4f94.tar.gz
tor-ca1f18c159fe2c46b32daf86334689afe2db4f94.zip
Merge branch 'tor-github/pr/1385'
-rw-r--r--changes/bug318984
-rw-r--r--src/lib/dispatch/.may_include1
-rw-r--r--src/lib/dispatch/dispatch_cfg.h6
-rw-r--r--src/lib/dispatch/dispatch_new.c12
-rw-r--r--src/test/test_dispatch.c29
5 files changed, 47 insertions, 5 deletions
diff --git a/changes/bug31898 b/changes/bug31898
new file mode 100644
index 0000000000..6f3e0a5465
--- /dev/null
+++ b/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.
diff --git a/src/lib/dispatch/.may_include b/src/lib/dispatch/.may_include
index 7f2df5859f..884f4c0dbc 100644
--- a/src/lib/dispatch/.may_include
+++ b/src/lib/dispatch/.may_include
@@ -8,3 +8,4 @@ lib/dispatch/*.h
lib/intmath/*.h
lib/log/*.h
lib/malloc/*.h
+lib/testsupport/*.h \ No newline at end of file
diff --git a/src/lib/dispatch/dispatch_cfg.h b/src/lib/dispatch/dispatch_cfg.h
index 61fade7240..348dce8d40 100644
--- a/src/lib/dispatch/dispatch_cfg.h
+++ b/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) */
diff --git a/src/lib/dispatch/dispatch_new.c b/src/lib/dispatch/dispatch_new.c
index b89ef43ea7..d8e59d610a 100644
--- a/src/lib/dispatch/dispatch_new.c
+++ b/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;
diff --git a/src/test/test_dispatch.c b/src/test/test_dispatch.c
index d6fe7e781a..a62c18e0c9 100644
--- a/src/test/test_dispatch.c
+++ b/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),