aboutsummaryrefslogtreecommitdiff
path: root/src/lib/net/inaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/net/inaddr.c')
-rw-r--r--src/lib/net/inaddr.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/lib/net/inaddr.c b/src/lib/net/inaddr.c
index 1a2406ce5f..d50ac2440c 100644
--- a/src/lib/net/inaddr.c
+++ b/src/lib/net/inaddr.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2019, The Tor Project, Inc. */
+ * Copyright (c) 2007-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -11,7 +11,9 @@
#include "lib/net/inaddr.h"
#include "lib/cc/torint.h"
+#include "lib/container/smartlist.h"
#include "lib/log/util_bug.h"
+#include "lib/malloc/malloc.h"
#include "lib/net/inaddr_st.h"
#include "lib/string/compat_ctype.h"
#include "lib/string/compat_string.h"
@@ -35,12 +37,31 @@
* (Like inet_aton(str,addr), but works on Windows and Solaris.)
*/
int
-tor_inet_aton(const char *str, struct in_addr* addr)
+tor_inet_aton(const char *str, struct in_addr *addr)
{
- unsigned a,b,c,d;
+ unsigned a, b, c, d;
char more;
- if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
+ bool is_octal = false;
+ smartlist_t *sl = NULL;
+
+ if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a, &b, &c, &d, &more) != 4)
+ return 0;
+
+ /* Parse the octets and check them for leading zeros. */
+ sl = smartlist_new();
+ smartlist_split_string(sl, str, ".", 0, 0);
+ SMARTLIST_FOREACH(sl, const char *, octet, {
+ is_octal = (strlen(octet) > 1 && octet[0] == '0');
+ if (is_octal) {
+ break;
+ }
+ });
+ SMARTLIST_FOREACH(sl, char *, octet, tor_free(octet));
+ smartlist_free(sl);
+
+ if (is_octal)
return 0;
+
if (a > 255) return 0;
if (b > 255) return 0;
if (c > 255) return 0;
@@ -168,6 +189,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 +235,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