diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-09-06 16:51:08 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-09-12 15:00:43 +0200 |
commit | 17cdd31e00b2ca2763c042a415bfcf03b614a783 (patch) | |
tree | 9604ddfc2bce866b4b4bccb145526ddd784e43f8 /bgpd/bgp_attr.c | |
parent | Merge pull request #2999 from donaldsharp/consistent (diff) | |
download | frr-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.c | 21 |
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: |