From: Stephen Worley Date: Sat, 21 Jul 2018 03:20:28 +0000 (-0400) Subject: zebra: Add check for prefix length from kernel messages X-Git-Tag: frr-6.1-dev~122^2~3 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=930571d24f051e2088b76e7e9eeed58b2bb51455;p=matthieu%2Ffrr.git zebra: Add check for prefix length from kernel messages Zebra needed a check that varifies the prefix length of an address is a valid length when receiving route changes and interface address changes. Signed-off-by: Stephen Worley --- diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 8f6e31cfa8..67b6704d6e 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -991,6 +991,12 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* Register interface address to the interface. */ if (ifa->ifa_family == AF_INET) { + if (ifa->ifa_prefixlen > IPV4_MAX_BITLEN) { + zlog_warn( + "Invalid prefix length: %d received from kernel interface addr change: %d", + ifa->ifa_prefixlen, h->nlmsg_type); + return 0; + } if (h->nlmsg_type == RTM_NEWADDR) connected_add_ipv4(ifp, flags, (struct in_addr *)addr, ifa->ifa_prefixlen, @@ -1001,6 +1007,12 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup) ifa->ifa_prefixlen, (struct in_addr *)broad); } if (ifa->ifa_family == AF_INET6) { + if (ifa->ifa_prefixlen > IPV6_MAX_BITLEN) { + zlog_warn( + "Invalid prefix length: %d received from kernel interface addr change: %d", + ifa->ifa_prefixlen, h->nlmsg_type); + return 0; + } if (h->nlmsg_type == RTM_NEWADDR) { /* Only consider valid addresses; we'll not get a * notification from diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 485abc3f12..8393ba6f24 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -384,17 +384,36 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, if (rtm->rtm_family == AF_INET) { p.family = AF_INET; + if (rtm->rtm_dst_len > IPV4_MAX_BITLEN) { + zlog_warn( + "Invalid destination prefix length: %d received from kernel route change", + rtm->rtm_dst_len); + return 0; + } memcpy(&p.u.prefix4, dest, 4); p.prefixlen = rtm->rtm_dst_len; src_p.prefixlen = 0; // Forces debug below to not display anything + } else if (rtm->rtm_family == AF_INET6) { p.family = AF_INET6; + if (rtm->rtm_dst_len > IPV6_MAX_BITLEN) { + zlog_warn( + "Invalid destination prefix length: %d received from kernel route change", + rtm->rtm_dst_len); + return 0; + } memcpy(&p.u.prefix6, dest, 16); p.prefixlen = rtm->rtm_dst_len; src_p.family = AF_INET6; + if (rtm->rtm_src_len > IPV6_MAX_BITLEN) { + zlog_warn( + "Invalid source prefix length: %d received from kernel route change", + rtm->rtm_src_len); + return 0; + } memcpy(&src_p.prefix, src, 16); src_p.prefixlen = rtm->rtm_src_len; }