about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2012-07-13 17:20:01 -0700
committerEric Wong <normalperson@yhbt.net>2012-07-13 17:20:01 -0700
commite594c55b95e49665ece6f026b9eac0891e8e56af (patch)
tree3c1cd808dcddcebd826f33669ff99989bc92a9a9
parent85ef3f28ad73ac6728cea9d6fc612fe9ab1110f9 (diff)
downloadrpatricia-for-tatsuya.tar.gz
patricia: fix bounds error in ascii2prefix for-tatsuya
When parsing network masks, we forget to update the length of
the IP address before scanning it for ':' to detect if an
address is IPv6 or not.  This caused memchr to falsely detect
':' past the end of string (but not the allocated array) if the
stack had a dirty ':' leftover.

Falsely detecting ':' leads to AF_INET6 being passed to
inet_pton() on some AF_INET (IPv4) addresses, causing
a failure.

Fortunately this bug could not cause a segfault or bus error
(and thus went undetected by valgrind).   The code was always
accessing memory within the stack allocated in the "save" array
of INET6_ADDRSTRLEN bytes.
-rw-r--r--ext/rpatricia/patricia.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/ext/rpatricia/patricia.c b/ext/rpatricia/patricia.c
index 94d8465..cf25167 100644
--- a/ext/rpatricia/patricia.c
+++ b/ext/rpatricia/patricia.c
@@ -170,12 +170,14 @@ ascii2prefix(char *string, prefix_t *prefix)
     slash = memchr(string, '/', len);
     if (slash) {
         bitlen = strtol(slash + 1, &end, 10);
-        if (*end || (bitlen < 0) || ((slash - string) >= (int)sizeof(save)))
+        len = slash - string;
+
+        if (*end || (bitlen < 0) || len >= sizeof(save))
             return NULL;
 
         /* copy the string to save. Avoid destroying the string */
-        memcpy(save, string, slash - string);
-        save[slash - string] = '\0';
+        memcpy(save, string, len);
+        save[len] = '\0';
         string = save;
     } else {
         bitlen = -1;