]> jfr.im git - irc/rizon/plexus4.git/commitdiff
hostmask: fix stack out of bounds write when parsing v6 netmasks
authorAdam <redacted>
Tue, 28 May 2019 17:20:30 +0000 (13:20 -0400)
committerAdam <redacted>
Tue, 28 May 2019 17:20:30 +0000 (13:20 -0400)
Additionally fix the check for the number of given cidr bits to be > the
number of parsed bits to not erronously parse valid v6 masks as hosts

src/hostmask.c
test/Makefile.am
test/plexus_test.h
test/test.c
test/tests/hostmask.c [new file with mode: 0644]

index 2030e979d2d9ea4d47e9c30098d2e3c08c27bfd6..92e33b3ec78623ec058bcc1a65bf81ed7d4f9a93 100644 (file)
@@ -110,13 +110,13 @@ try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
     {
       char *after;
 
-      d[dp] = d[dp] >> 4 * nyble;
-      dp++;
       bits = strtoul(p + 1, &after, 10);
 
-      if (bits < 0 || *after)
+      if (bits < 0 || bits > 128 || *after)
         return HM_HOST;
-      if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
+
+      // 16 bits for each hextet, plus 4 for each parsed nyble
+      if (bits > dp * 16 + (4 - nyble) * 4 && !(finsert >= 0))
         return HM_HOST;
       break;
     }
@@ -124,6 +124,7 @@ try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
       return HM_HOST;
   }
 
+  assert(dp < 8);
   d[dp] = d[dp] >> 4 * nyble;
 
   if (c == 0)
index 5eccb83ae70aceef95daaaa1db445b106394cef6..9a63a88cd531ea91e18b5fd155b19d7919ed1683 100644 (file)
@@ -33,7 +33,8 @@ check_plexus_SOURCES = \
        tests/privmsg.c \
        tests/session.c \
        tests/upgrade.c \
-       tests/webirc.c
+       tests/webirc.c \
+       tests/hostmask.c
 
 uninstall-local:
        ${RM} -f test.log trs.log
index 413e2419fb71e3d022e20f1fc468eefd41864b3e..7e0b0ad2c391289543ee295208541ad13d46b452 100644 (file)
@@ -82,6 +82,7 @@ extern void privmsg_setup(Suite *s);
 extern void ping_setup(Suite *s);
 extern void webirc_setup(Suite *s);
 extern void cloak_setup(Suite *s);
+extern void hostmask_setup(Suite *s);
 
 #define tlog(fmt, ...) plexus_log(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
 extern void plexus_log(const char *, int, const char *, ...);
index 79c4c2b8cc60d1b16030af24d326f6d61bc913b9..d0c02bd4353febbd7d16b95eba88bb5ea55e13aa 100644 (file)
@@ -43,6 +43,7 @@ add_testcases(Suite *s)
   ping_setup(s);
   webirc_setup(s);
   cloak_setup(s);
+  hostmask_setup(s);
 }
 
 int
diff --git a/test/tests/hostmask.c b/test/tests/hostmask.c
new file mode 100644 (file)
index 0000000..64b16be
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *
+ *  Copyright (C) 2019 Adam <Adam@anope.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ */
+
+#include "plexus_test.h"
+
+START_TEST(hostmask_test)
+{
+  ck_assert_int_eq(parse_netmask("0000:0000:0000:0000:0000:0000:0000:0001/1", NULL, NULL), HM_IPV6);
+  ck_assert_int_eq(parse_netmask("0000:0000:0000:0000:0000:0000:0000:1000/127", NULL, NULL), HM_IPV6);
+}
+END_TEST
+
+void
+hostmask_setup(Suite *s)
+{
+  TCase *tc = tcase_create("hostmask");
+
+  tcase_add_test(tc, hostmask_test);
+
+  suite_add_tcase(s, tc);
+}