From 23ed863da4f66d9e07f578118f328b9f1898fe52 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Fri, 31 Aug 2018 18:55:36 +0300 Subject: [PATCH 1/6] Improve bracket handling in tor_addr_parse() * Actually check for second bracket * Only attempt parsing IPv4 address when no brackets found --- src/lib/net/address.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 619fa13e9b..14c086a5b0 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -1187,14 +1187,19 @@ tor_addr_parse(tor_addr_t *addr, const char *src) int result; struct in_addr in_tmp; struct in6_addr in6_tmp; + int brackets_detected = 0; + tor_assert(addr && src); - if (src[0] == '[' && src[1]) + if (src[0] == '[' && src[1] && src[strlen(src)-1] == ']') { + brackets_detected = 1; src = tmp = tor_strndup(src+1, strlen(src)-2); + } if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) { result = AF_INET6; tor_addr_from_in6(addr, &in6_tmp); - } else if (tor_inet_pton(AF_INET, src, &in_tmp) > 0) { + } else if (!brackets_detected && + tor_inet_pton(AF_INET, src, &in_tmp) > 0) { result = AF_INET; tor_addr_from_in(addr, &in_tmp); } else { From feae813e1bf32e7fc35a14d88ece4a9457cfd172 Mon Sep 17 00:00:00 2001 From: David Fifield Date: Wed, 2 Aug 2017 02:04:35 -0700 Subject: [PATCH 2/6] Add tests for tor_addr_parse, separate from tor_addr_port_parse. --- src/test/test_addr.c | 56 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/test/test_addr.c b/src/test/test_addr.c index a9004048a5..1d97db52a6 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -723,7 +723,7 @@ test_addr_ip6_helpers(void *arg) ; } -/** Test tor_addr_port_parse(). */ +/** Test tor_addr_parse() and tor_addr_port_parse(). */ static void test_addr_parse(void *arg) { @@ -734,6 +734,60 @@ test_addr_parse(void *arg) /* Correct call. */ (void)arg; + r= tor_addr_parse(&addr, "192.0.2.1"); + tt_int_op(r,OP_EQ, AF_INET); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + tt_str_op(buf,OP_EQ, "192.0.2.1"); + + r= tor_addr_parse(&addr, "11:22::33:44"); + tt_int_op(r,OP_EQ, AF_INET6); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + tt_str_op(buf,OP_EQ, "11:22::33:44"); + + r= tor_addr_parse(&addr, "[11:22::33:44]"); + tt_int_op(r,OP_EQ, AF_INET6); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + tt_str_op(buf,OP_EQ, "11:22::33:44"); + + r= tor_addr_parse(&addr, "11:22:33:44:55:66:1.2.3.4"); + tt_int_op(r,OP_EQ, AF_INET6); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + tt_str_op(buf,OP_EQ, "11:22:33:44:55:66:102:304"); + + r= tor_addr_parse(&addr, "11:22::33:44:1.2.3.4"); + tt_int_op(r,OP_EQ, AF_INET6); + tor_addr_to_str(buf, &addr, sizeof(buf), 0); + tt_str_op(buf,OP_EQ, "11:22::33:44:102:304"); + + /* Empty string. */ + r= tor_addr_parse(&addr, ""); + tt_int_op(r,OP_EQ, -1); + + /* Square brackets around IPv4 address. */ + r= tor_addr_parse(&addr, "[192.0.2.1]"); + tt_int_op(r,OP_EQ, -1); + + /* Only left square bracket. */ + r= tor_addr_parse(&addr, "[11:22::33:44"); + tt_int_op(r,OP_EQ, -1); + + /* Only right square bracket. */ + r= tor_addr_parse(&addr, "11:22::33:44]"); + tt_int_op(r,OP_EQ, -1); + + /* Leading colon. */ + r= tor_addr_parse(&addr, ":11:22::33:44"); + tt_int_op(r,OP_EQ, -1); + + /* Trailing colon. */ + r= tor_addr_parse(&addr, "11:22::33:44:"); + tt_int_op(r,OP_EQ, -1); + + /* Too many hex words in IPv4-mapped IPv6 address. */ + r= tor_addr_parse(&addr, "11:22:33:44:55:66:77:88:1.2.3.4"); + tt_int_op(r,OP_EQ, -1); + + /* Correct call. */ r= tor_addr_port_parse(LOG_DEBUG, "192.0.2.1:1234", &addr, &port, -1); From 01eb164574bdcc938509810634dfb0348c484662 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Fri, 31 Aug 2018 19:34:14 +0300 Subject: [PATCH 3/6] Reject addresses with needless trailing colon --- src/lib/net/address.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 14c086a5b0..336693b464 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -1189,13 +1189,19 @@ tor_addr_parse(tor_addr_t *addr, const char *src) struct in6_addr in6_tmp; int brackets_detected = 0; + size_t len = strlen(src); + tor_assert(addr && src); - if (src[0] == '[' && src[1] && src[strlen(src)-1] == ']') { + if (src[0] == '[' && src[1] && src[len - 1] == ']') { brackets_detected = 1; src = tmp = tor_strndup(src+1, strlen(src)-2); + len -= 2; } - if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) { + /* Reject if src has needless trailing ':'. */ + if (len > 2 && src[len - 1] == ':' && src[len - 2] != ':') { + result = -1; + } else if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) { result = AF_INET6; tor_addr_from_in6(addr, &in6_tmp); } else if (!brackets_detected && From 1baa2703c36cf964d5fc1f07433196e8ccc0e55a Mon Sep 17 00:00:00 2001 From: rl1987 Date: Fri, 31 Aug 2018 20:05:54 +0300 Subject: [PATCH 4/6] Add changes file --- changes/bug23082 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/bug23082 diff --git a/changes/bug23082 b/changes/bug23082 new file mode 100644 index 0000000000..fc4b52c364 --- /dev/null +++ b/changes/bug23082 @@ -0,0 +1,4 @@ + o Minor bugfixes (networking): + - Introduce additional checks into tor_addr_parse() to + reject certain incorrect inputs that previously were + not detected. Fixes bug 23082; bugfix on 0.2.0.10-alpha. From 742cd1564993faefded2d33b6839428a1fe4412a Mon Sep 17 00:00:00 2001 From: rl1987 Date: Sat, 1 Sep 2018 20:56:33 +0300 Subject: [PATCH 5/6] Move a check for trailing colon to tor_inet_pton() That way, string_is_valid_ipv6_address() can benefit from it --- src/lib/net/address.c | 5 +---- src/lib/net/inaddr.c | 8 +++++++- src/test/test_util.c | 13 +++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 336693b464..17f4b1cf7a 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -1198,10 +1198,7 @@ tor_addr_parse(tor_addr_t *addr, const char *src) len -= 2; } - /* Reject if src has needless trailing ':'. */ - if (len > 2 && src[len - 1] == ':' && src[len - 2] != ':') { - result = -1; - } else if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) { + if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) { result = AF_INET6; tor_addr_from_in6(addr, &in6_tmp); } else if (!brackets_detected && diff --git a/src/lib/net/inaddr.c b/src/lib/net/inaddr.c index dcd8fcdd65..0960d323c5 100644 --- a/src/lib/net/inaddr.c +++ b/src/lib/net/inaddr.c @@ -168,6 +168,13 @@ tor_inet_pton(int af, const char *src, void *dst) if (af == AF_INET) { return tor_inet_aton(src, dst); } else if (af == AF_INET6) { + ssize_t len = strlen(src); + + /* Reject if src has needless trailing ':'. */ + if (len > 2 && src[len - 1] == ':' && src[len - 2] != ':') { + return 0; + } + struct in6_addr *out = dst; uint16_t words[8]; int gapPos = -1, i, setWords=0; @@ -207,7 +214,6 @@ tor_inet_pton(int af, const char *src, void *dst) return 0; if (TOR_ISXDIGIT(*src)) { char *next; - ssize_t len; long r = strtol(src, &next, 16); if (next == NULL || next == src) { /* The 'next == src' error case can happen on versions of openbsd diff --git a/src/test/test_util.c b/src/test/test_util.c index 6cbd504e34..0921bae109 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -5749,6 +5749,18 @@ test_util_ipv4_validation(void *arg) return; } +static void +test_util_ipv6_validation(void *arg) +{ + (void)arg; + + tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e")); + tt_assert(!string_is_valid_ipv6_address("11:22::33:44:")); + + done: + return; +} + static void test_util_writepid(void *arg) { @@ -6439,6 +6451,7 @@ struct testcase_t util_tests[] = { UTIL_TEST(hostname_validation, 0), UTIL_TEST(dest_validation_edgecase, 0), UTIL_TEST(ipv4_validation, 0), + UTIL_TEST(ipv6_validation, 0), UTIL_TEST(writepid, 0), UTIL_TEST(get_avail_disk_space, 0), UTIL_TEST(touch_file, 0), From 1425549ca61cab8aa9476a25be0a31f726672bcc Mon Sep 17 00:00:00 2001 From: rl1987 Date: Sat, 1 Sep 2018 21:22:47 +0300 Subject: [PATCH 6/6] Code cleanups for tor_addr_parse() --- src/lib/net/address.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/net/address.c b/src/lib/net/address.c index 17f4b1cf7a..a87d4a36a3 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -1189,13 +1189,13 @@ tor_addr_parse(tor_addr_t *addr, const char *src) struct in6_addr in6_tmp; int brackets_detected = 0; + tor_assert(addr && src); + size_t len = strlen(src); - tor_assert(addr && src); - if (src[0] == '[' && src[1] && src[len - 1] == ']') { + if (len && src[0] == '[' && src[len - 1] == ']') { brackets_detected = 1; src = tmp = tor_strndup(src+1, strlen(src)-2); - len -= 2; } if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) {