]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Validate large-community-list against UINT_MAX
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Tue, 2 Jul 2019 12:35:26 +0000 (15:35 +0300)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Sun, 7 Jul 2019 08:35:30 +0000 (11:35 +0300)
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
bgpd/bgp_clist.c

index 3a93db1ac6cea8d4f190716d675912ed5f7ddff0..227aaf96f1f4a375fcfda97044dd1b471a52d9d6 100644 (file)
@@ -26,6 +26,7 @@
 #include "queue.h"
 #include "filter.h"
 #include "stream.h"
+#include "frrstr.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_community.h"
@@ -971,6 +972,33 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
        return lcom;
 }
 
+/* Helper to check if every octet do not exceed UINT_MAX */
+static int lcommunity_list_valid(const char *community)
+{
+       int octets = 0;
+       char **splits;
+       int num;
+
+       frrstr_split(community, ":", &splits, &num);
+
+       for (int i = 0; i < num; i++) {
+               if (strtoul(splits[i], NULL, 10) > UINT_MAX)
+                       return 0;
+
+               if (strlen(splits[i]) == 0)
+                       return 0;
+
+               octets++;
+               XFREE(MTYPE_TMP, splits[i]);
+       }
+       XFREE(MTYPE_TMP, splits);
+
+       if (octets < 3)
+               return 0;
+
+       return 1;
+}
+
 /* Set lcommunity-list.  */
 int lcommunity_list_set(struct community_list_handler *ch, const char *name,
                        const char *str, int direct, int style)
@@ -999,6 +1027,9 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
        }
 
        if (str) {
+               if (!lcommunity_list_valid(str))
+                       return COMMUNITY_LIST_ERR_MALFORMED_VAL;
+
                if (style == LARGE_COMMUNITY_LIST_STANDARD)
                        lcom = lcommunity_str2com(str);
                else