mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 15:17:15 +00:00
bgpd: Fix buffer overflow error in bgp_dump_routes_func
Now if the number of entries for some prefix is too large, multiple TABLE_DUMP_V2 records are created. In the previous version in such situation bgpd crashed with SIGABRT.
This commit is contained in:
parent
cbac2b1b92
commit
246556b504
@ -299,42 +299,17 @@ bgp_dump_routes_index_table(struct bgp *bgp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Runs under child process. */
|
static struct bgp_info *
|
||||||
static unsigned int
|
bgp_dump_route_node_record (int afi, struct bgp_node *rn,
|
||||||
bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
|
struct bgp_info *info, unsigned int seq)
|
||||||
{
|
{
|
||||||
struct stream *obuf;
|
struct stream *obuf;
|
||||||
struct bgp_info *info;
|
size_t sizep;
|
||||||
struct bgp_node *rn;
|
size_t endp;
|
||||||
struct bgp *bgp;
|
|
||||||
struct bgp_table *table;
|
|
||||||
|
|
||||||
bgp = bgp_get_default ();
|
|
||||||
if (!bgp)
|
|
||||||
return seq;
|
|
||||||
|
|
||||||
if (bgp_dump_routes.fp == NULL)
|
|
||||||
return seq;
|
|
||||||
|
|
||||||
/* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
|
|
||||||
so this should only be done on the first call to bgp_dump_routes_func.
|
|
||||||
( this function will be called once for ipv4 and once for ipv6 ) */
|
|
||||||
if(first_run)
|
|
||||||
bgp_dump_routes_index_table(bgp);
|
|
||||||
|
|
||||||
obuf = bgp_dump_obuf;
|
obuf = bgp_dump_obuf;
|
||||||
stream_reset (obuf);
|
stream_reset (obuf);
|
||||||
|
|
||||||
/* Walk down each BGP route. */
|
|
||||||
table = bgp->rib[afi][SAFI_UNICAST];
|
|
||||||
|
|
||||||
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
|
|
||||||
{
|
|
||||||
if(!rn->info)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
stream_reset(obuf);
|
|
||||||
|
|
||||||
/* MRT header */
|
/* MRT header */
|
||||||
if (afi == AFI_IP)
|
if (afi == AFI_IP)
|
||||||
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
|
bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV4_UNICAST,
|
||||||
@ -362,7 +337,7 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save where we are now, so we can overwride the entry count later */
|
/* Save where we are now, so we can overwride the entry count later */
|
||||||
int sizep = stream_get_endp(obuf);
|
sizep = stream_get_endp (obuf);
|
||||||
|
|
||||||
/* Entry count */
|
/* Entry count */
|
||||||
uint16_t entry_count = 0;
|
uint16_t entry_count = 0;
|
||||||
@ -370,9 +345,10 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
|
|||||||
/* Entry count, note that this is overwritten later */
|
/* Entry count, note that this is overwritten later */
|
||||||
stream_putw (obuf, 0);
|
stream_putw (obuf, 0);
|
||||||
|
|
||||||
for (info = rn->info; info; info = info->next)
|
endp = stream_get_endp (obuf);
|
||||||
|
for (; info; info = info->next)
|
||||||
{
|
{
|
||||||
entry_count++;
|
size_t cur_endp;
|
||||||
|
|
||||||
/* Peer index */
|
/* Peer index */
|
||||||
stream_putw (obuf, info->peer->table_dump_index);
|
stream_putw (obuf, info->peer->table_dump_index);
|
||||||
@ -387,16 +363,62 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
|
|||||||
/* Dump attribute. */
|
/* Dump attribute. */
|
||||||
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
/* Skip prefix & AFI/SAFI for MP_NLRI */
|
||||||
bgp_dump_routes_attr (obuf, info->attr, &rn->p);
|
bgp_dump_routes_attr (obuf, info->attr, &rn->p);
|
||||||
|
|
||||||
|
cur_endp = stream_get_endp (obuf);
|
||||||
|
if (cur_endp > BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
||||||
|
+ BGP_DUMP_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
stream_set_endp (obuf, endp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_count++;
|
||||||
|
endp = cur_endp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overwrite the entry count, now that we know the right number */
|
/* Overwrite the entry count, now that we know the right number */
|
||||||
stream_putw_at (obuf, sizep, entry_count);
|
stream_putw_at (obuf, sizep, entry_count);
|
||||||
|
|
||||||
seq++;
|
|
||||||
|
|
||||||
bgp_dump_set_size (obuf, MSG_TABLE_DUMP_V2);
|
bgp_dump_set_size (obuf, MSG_TABLE_DUMP_V2);
|
||||||
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
|
fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Runs under child process. */
|
||||||
|
static unsigned int
|
||||||
|
bgp_dump_routes_func (int afi, int first_run, unsigned int seq)
|
||||||
|
{
|
||||||
|
struct bgp_info *info;
|
||||||
|
struct bgp_node *rn;
|
||||||
|
struct bgp *bgp;
|
||||||
|
struct bgp_table *table;
|
||||||
|
|
||||||
|
bgp = bgp_get_default ();
|
||||||
|
if (!bgp)
|
||||||
|
return seq;
|
||||||
|
|
||||||
|
if (bgp_dump_routes.fp == NULL)
|
||||||
|
return seq;
|
||||||
|
|
||||||
|
/* Note that bgp_dump_routes_index_table will do ipv4 and ipv6 peers,
|
||||||
|
so this should only be done on the first call to bgp_dump_routes_func.
|
||||||
|
( this function will be called once for ipv4 and once for ipv6 ) */
|
||||||
|
if (first_run)
|
||||||
|
bgp_dump_routes_index_table(bgp);
|
||||||
|
|
||||||
|
/* Walk down each BGP route. */
|
||||||
|
table = bgp->rib[afi][SAFI_UNICAST];
|
||||||
|
|
||||||
|
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
|
||||||
|
{
|
||||||
|
info = rn->info;
|
||||||
|
while (info)
|
||||||
|
{
|
||||||
|
info = bgp_dump_route_node_record (afi, rn, info, seq);
|
||||||
|
seq++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush (bgp_dump_routes.fp);
|
fflush (bgp_dump_routes.fp);
|
||||||
@ -843,8 +865,8 @@ bgp_dump_init (void)
|
|||||||
memset (&bgp_dump_updates, 0, sizeof (struct bgp_dump));
|
memset (&bgp_dump_updates, 0, sizeof (struct bgp_dump));
|
||||||
memset (&bgp_dump_routes, 0, sizeof (struct bgp_dump));
|
memset (&bgp_dump_routes, 0, sizeof (struct bgp_dump));
|
||||||
|
|
||||||
bgp_dump_obuf = stream_new (BGP_MAX_PACKET_SIZE + BGP_DUMP_MSG_HEADER
|
bgp_dump_obuf = stream_new ((BGP_MAX_PACKET_SIZE << 1)
|
||||||
+ BGP_DUMP_HEADER_SIZE);
|
+ BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE);
|
||||||
|
|
||||||
install_node (&bgp_dump_node, config_write_bgp_dump);
|
install_node (&bgp_dump_node, config_write_bgp_dump);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user