From: Donatas Abraitis Date: Tue, 2 Jul 2019 12:35:26 +0000 (+0300) Subject: bgpd: Validate large-community-list against UINT_MAX X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=653eab614945e110b99a23c6ebb62c21b288170e;p=matthieu%2Ffrr.git bgpd: Validate large-community-list against UINT_MAX Signed-off-by: Donatas Abraitis --- diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index e308e963b5..837caca41e 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -27,6 +27,7 @@ #include "filter.h" #include "stream.h" #include "jhash.h" +#include "frrstr.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_community.h" @@ -1000,6 +1001,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) @@ -1028,6 +1056,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