summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-09-06 16:51:08 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-09-12 15:00:43 +0200
commit17cdd31e00b2ca2763c042a415bfcf03b614a783 (patch)
tree9604ddfc2bce866b4b4bccb145526ddd784e43f8 /bgpd/bgp_attr.c
parentMerge pull request #2999 from donaldsharp/consistent (diff)
downloadfrr-17cdd31e00b2ca2763c042a415bfcf03b614a783.tar.xz
frr-17cdd31e00b2ca2763c042a415bfcf03b614a783.zip
bgpd: Prevent possible crash when parsing v6 attributes
The peer->nexthop.ifp pointer must be set when parsing the attributes in bgp_mp_reach_parse, notice this and fail gracefully. Rework bgp_nexthop_set to remove the HAVE_CUMULUS and to fail the nexthop_set when we have a zebra connection and no ifp pointer, as that not havinga zebra connection and no ifp pointer is legal. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 6acd4c8cf..720afe6e0 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1707,8 +1707,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
stream_getl(s); /* RD low */
}
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
- if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+ if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: interface not set appropriately to handle some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+ }
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
@@ -1718,8 +1724,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
stream_getl(s); /* RD low */
}
stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
- if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+ if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: interface not set appropriately to handle some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+ }
if (attr->mp_nexthop_len
== BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
stream_getl(s); /* RD high */
@@ -1743,6 +1755,11 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
}
+ if (!peer->nexthop.ifp) {
+ zlog_warn("%s: Interface not set appropriately to handle this some attributes",
+ peer->host);
+ return BGP_ATTR_PARSE_WITHDRAW;
+ }
attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
break;
default: