forked from Mirror/frr
Correct a few fuzz failures in BGP
This commit is contained in:
parent
7a4bb9c54e
commit
b184ccd889
|
@ -1148,14 +1148,9 @@ bgp_attr_nexthop (struct bgp_attr_parser_args *args)
|
|||
args->total);
|
||||
}
|
||||
|
||||
/* According to section 6.3 of RFC4271, syntactically incorrect NEXT_HOP
|
||||
attribute must result in a NOTIFICATION message (this is implemented below).
|
||||
At the same time, semantically incorrect NEXT_HOP is more likely to be just
|
||||
logged locally (this is implemented somewhere else). The UPDATE message
|
||||
gets ignored in any of these cases. */
|
||||
nexthop_n = stream_get_ipv4 (peer->ibuf);
|
||||
nexthop_h = ntohl (nexthop_n);
|
||||
if (IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
|
||||
if (!bgp_valid_host_address(nexthop_h))
|
||||
{
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
|
||||
|
@ -1864,9 +1859,10 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
|
|||
if (attr_endp > endp)
|
||||
{
|
||||
zlog_warn ("%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp);
|
||||
bgp_notify_send (peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
|
||||
bgp_notify_send_with_data (peer,
|
||||
BGP_NOTIFY_UPDATE_ERR,
|
||||
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
|
||||
startp, attr_endp - startp);
|
||||
return BGP_ATTR_PARSE_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -1343,6 +1343,34 @@ bgp_collision_detect (struct peer *new, struct in_addr remote_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* per draft-ietf-idr-error-handling-13
|
||||
*
|
||||
* An IP host address SHOULD be considered invalid if it appears in the
|
||||
* "IANA IPv4 Special-Purpose Address Registry" [IANA-IPV4] and either
|
||||
* the "destination" or the "forwardable" boolean in that registry is
|
||||
* given as "false".
|
||||
*/
|
||||
int
|
||||
bgp_valid_host_address (unsigned long addr)
|
||||
{
|
||||
if (IPV4_NET0(addr) || // 0.0.0.0/8
|
||||
IPV4_NET127(addr) || // 127.0.0.0/8
|
||||
IPV4_LINKLOCAL(addr) || // 169.254.0.0/16
|
||||
addr == 0xC00000AA || // 192.0.0.170/32
|
||||
addr == 0xC00000AB || // 192.0.0.171/32
|
||||
(addr & 0xffffff00) == 0xC0000200 || // 192.0.2.0/24
|
||||
(addr & 0xffffff00) == 0xC6336400 || // 198.51.100.0/24
|
||||
(addr & 0xffffff00) == 0xCB007100 || // 203.0.113.0/24
|
||||
IPV4_CLASS_DE(addr))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bgp_open_receive (struct peer *peer, bgp_size_t size)
|
||||
{
|
||||
|
@ -1358,11 +1386,15 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
|
|||
int mp_capability;
|
||||
u_int8_t notify_data_remote_as[2];
|
||||
u_int8_t notify_data_remote_id[4];
|
||||
u_int16_t *holdtime_ptr;
|
||||
unsigned long local_addr;
|
||||
unsigned long remote_addr;
|
||||
|
||||
/* Parse open packet. */
|
||||
version = stream_getc (peer->ibuf);
|
||||
memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
|
||||
remote_as = stream_getw (peer->ibuf);
|
||||
holdtime_ptr = stream_pnt (peer->ibuf);
|
||||
holdtime = stream_getw (peer->ibuf);
|
||||
memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
|
||||
remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
|
||||
|
@ -1438,10 +1470,11 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
|
|||
}
|
||||
}
|
||||
|
||||
local_addr = ntohl (peer->local_id.s_addr);
|
||||
remote_addr = ntohl (remote_id.s_addr);
|
||||
|
||||
/* remote router-id check. */
|
||||
if (remote_id.s_addr == 0
|
||||
|| IPV4_CLASS_DE (ntohl (remote_id.s_addr))
|
||||
|| ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
|
||||
if (local_addr == remote_addr || !bgp_valid_host_address(remote_addr))
|
||||
{
|
||||
if (bgp_debug_neighbor_events(peer))
|
||||
zlog_debug ("%s bad OPEN, wrong router identifier %s",
|
||||
|
@ -1493,9 +1526,10 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
|
|||
|
||||
if (holdtime < 3 && holdtime != 0)
|
||||
{
|
||||
bgp_notify_send (peer,
|
||||
BGP_NOTIFY_OPEN_ERR,
|
||||
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
|
||||
bgp_notify_send_with_data (peer,
|
||||
BGP_NOTIFY_OPEN_ERR,
|
||||
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
|
||||
holdtime_ptr, 2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,4 +66,5 @@ extern void bgp_check_update_delay (struct bgp *);
|
|||
extern int bgp_peer_wd_fifo_exists (struct peer *);
|
||||
extern int bgp_peer_adv_fifo_exists (struct peer *, int);
|
||||
extern void bgp_peer_schedule_updates(struct peer *peer);
|
||||
extern int bgp_valid_host_address (unsigned long addr);
|
||||
#endif /* _QUAGGA_BGP_PACKET_H */
|
||||
|
|
Loading…
Reference in a new issue