From 5bd66e2dcc8ab335ce7f2dd3c0baa3020f89a993 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 2 Jul 2019 15:35:26 +0300 Subject: [PATCH] bgpd: Validate large-community-list against UINT_MAX Signed-off-by: Donatas Abraitis --- bgpd/bgp_clist.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index ce617fe6b5..ff2ea6f7cd 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" @@ -1026,6 +1027,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) @@ -1054,6 +1082,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 -- 2.39.5