diff options
| author | Garrett D'Amore <garrett@damore.org> | 2019-12-31 15:09:20 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-01-01 08:47:06 -0800 |
| commit | a693a53e2302fe9cc60c1b5d2bf59c42032b20a3 (patch) | |
| tree | e98ba805ea9adc2e5ee3e33f7dea1c32584d5c63 /src | |
| parent | 0ab3403ef9407db4604cbb451c42a179ab807342 (diff) | |
| download | nng-a693a53e2302fe9cc60c1b5d2bf59c42032b20a3.tar.gz nng-a693a53e2302fe9cc60c1b5d2bf59c42032b20a3.tar.bz2 nng-a693a53e2302fe9cc60c1b5d2bf59c42032b20a3.zip | |
fixes #1081 Use after free possible in stats
fixes #1080 Desire better way to access statistics for NNG objects
We've also added a test that uses some of this, in order to verify
that the req protocol rejects invalid peers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/stats.c | 80 | ||||
| -rw-r--r-- | src/core/stats.h | 3 | ||||
| -rw-r--r-- | src/protocol/reqrep0/reqrep_test.c | 32 | ||||
| -rw-r--r-- | src/supplemental/util/platform.c | 1 |
4 files changed, 93 insertions, 23 deletions
diff --git a/src/core/stats.c b/src/core/stats.c index 3c200fec..d526014a 100644 --- a/src/core/stats.c +++ b/src/core/stats.c @@ -17,8 +17,8 @@ typedef struct nng_stat nni_stat; struct nng_stat { char * s_name; - const char * s_desc; - const char * s_string; + char * s_desc; + char * s_string; uint64_t s_value; nni_time s_time; nni_stat_type s_type; @@ -182,17 +182,6 @@ nni_stat_set_value(nni_stat_item *stat, uint64_t v) } void -nni_stat_set_string(nni_stat_item *stat, const char *str) -{ -#ifdef NNG_ENABLE_STATS - stat->si_string = str; -#else - NNI_ARG_UNUSED(stat); - NNI_ARG_UNUSED(str); -#endif -} - -void nni_stat_set_lock(nni_stat_item *stat, nni_mtx *mtx) { #ifdef NNG_ENABLE_STATS @@ -241,6 +230,8 @@ nng_stats_free(nni_stat *st) nng_stats_free(child); } nni_strfree(st->s_name); + nni_strfree(st->s_desc); + nni_strfree(st->s_string); NNI_FREE_STRUCT(st); #else NNI_ARG_UNUSED(st); @@ -257,15 +248,21 @@ stat_make_tree(nni_stat_item *item, nni_stat **sp) if ((stat = NNI_ALLOC_STRUCT(stat)) == NULL) { return (NNG_ENOMEM); } - if ((stat->s_name = nni_strdup(item->si_name)) == NULL) { - NNI_FREE_STRUCT(stat); + NNI_LIST_INIT(&stat->s_children, nni_stat, s_node); + + if (((stat->s_name = nni_strdup(item->si_name)) == NULL) || + ((stat->s_desc = nni_strdup(item->si_desc)) == NULL)) { + nng_stats_free(stat); + return (NNG_ENOMEM); + } + if ((item->si_type == NNG_STAT_STRING) && + ((stat->s_string = nni_strdup(item->si_string)) == NULL)) { + nng_stats_free(stat); return (NNG_ENOMEM); } - NNI_LIST_INIT(&stat->s_children, nni_stat, s_node); stat->s_item = item; stat->s_type = item->si_type; stat->s_unit = item->si_unit; - stat->s_desc = item->si_desc; stat->s_parent = NULL; NNI_LIST_FOREACH (&item->si_children, child) { @@ -300,9 +297,8 @@ stat_update(nni_stat *stat) if (item->si_update != NULL) { item->si_update(item, item->si_private); } - stat->s_value = item->si_number; - stat->s_string = item->si_string; - stat->s_time = nni_clock(); + stat->s_value = item->si_number; + stat->s_time = nni_clock(); } static void @@ -418,6 +414,49 @@ nng_stat_desc(nng_stat *stat) return (stat->s_desc); } +nng_stat * +nng_stat_find(nng_stat *stat, const char *name) +{ + nng_stat *child; + nng_stat *result; + if (stat == NULL) { + return (NULL); + } + if (strcmp(name, stat->s_name) == 0) { + return (stat); + } + NNI_LIST_FOREACH(&stat->s_children, child) { + if ((result = nng_stat_find(child, name)) != NULL) { + return (result); + } + } + return (NULL); +} + +nng_stat * +nng_stat_find_socket(nng_stat *stat, nng_socket s) +{ + char name[16]; + (void) snprintf(name, sizeof (name), "socket%d", nng_socket_id(s)); + return (nng_stat_find(stat, name)); +} + +nng_stat * +nng_stat_find_dialer(nng_stat *stat, nng_dialer d) +{ + char name[16]; + (void) snprintf(name, sizeof (name), "dialer%d", nng_dialer_id(d)); + return (nng_stat_find(stat, name)); +} + +nng_stat * +nng_stat_find_listener(nng_stat *stat, nng_listener l) +{ + char name[16]; + (void) snprintf(name, sizeof (name), "listener%d", nng_listener_id(l)); + return (nng_stat_find(stat, name)); +} + int nni_stat_sys_init(void) { @@ -427,7 +466,6 @@ nni_stat_sys_init(void) stats_root.si_name = ""; stats_root.si_desc = "all statistics"; #endif - return (0); } diff --git a/src/core/stats.h b/src/core/stats.h index 12dbbbdd..a9ea6e13 100644 --- a/src/core/stats.h +++ b/src/core/stats.h @@ -1,5 +1,5 @@ // -// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech> +// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech> // Copyright 2018 Capitar IT Group BV <info@capitar.com> // // This software is supplied under the terms of the MIT License, a @@ -66,7 +66,6 @@ void nni_stat_register(nni_stat_item *); void nni_stat_unregister(nni_stat_item *); void nni_stat_set_value(nni_stat_item *, uint64_t); -void nni_stat_set_string(nni_stat_item *, const char *); void nni_stat_set_lock(nni_stat_item *, nni_mtx *); void nni_stat_set_update(nni_stat_item *, nni_stat_update, void *); diff --git a/src/protocol/reqrep0/reqrep_test.c b/src/protocol/reqrep0/reqrep_test.c index b68c08cb..f4617936 100644 --- a/src/protocol/reqrep0/reqrep_test.c +++ b/src/protocol/reqrep0/reqrep_test.c @@ -387,6 +387,37 @@ test_req_context_not_pollable(void) TEST_NNG_PASS(nng_close(req)); } +void +test_req_validate_peer(void) +{ + nng_socket s1, s2; + nng_stat * stats; + nng_stat * reject; + char addr[64]; + + testutil_scratch_addr("inproc", sizeof(addr), addr); + + TEST_NNG_PASS(nng_req0_open(&s1)); + TEST_NNG_PASS(nng_req0_open(&s2)); + + TEST_NNG_PASS(nng_listen(s1, addr, NULL, 0)); + TEST_NNG_PASS(nng_dial(s2, addr, NULL, NNG_FLAG_NONBLOCK)); + + testutil_sleep(100); + TEST_NNG_PASS(nng_stats_get(&stats)); + + TEST_CHECK(stats != NULL); + TEST_CHECK((reject = nng_stat_find_socket(stats, s1)) != NULL); + TEST_CHECK((reject = nng_stat_find(reject, "reject")) != NULL); + + TEST_CHECK(nng_stat_type(reject) == NNG_STAT_COUNTER); + TEST_CHECK(nng_stat_value(reject) > 0); + + TEST_NNG_PASS(nng_close(s1)); + TEST_NNG_PASS(nng_close(s2)); + nng_stats_free(stats); +} + TEST_LIST = { { "req rep identity", test_req_rep_identity }, { "resend option", test_resend_option }, @@ -398,5 +429,6 @@ TEST_LIST = { { "req poll writable", test_req_poll_writeable }, { "req poll readable", test_req_poll_readable }, { "req context not pollable", test_req_context_not_pollable }, + { "req validate peer", test_req_validate_peer }, { NULL, NULL }, }; diff --git a/src/supplemental/util/platform.c b/src/supplemental/util/platform.c index 138e8b0b..468582bd 100644 --- a/src/supplemental/util/platform.c +++ b/src/supplemental/util/platform.c @@ -155,5 +155,6 @@ nng_cv_wake1(nng_cv *cv) uint32_t nng_random(void) { + (void) nni_init(); return (nni_random()); } |
