Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Maintenance:5061
quagga.openSUSE_Leap_42.1_Update
quagga-CVE-2016-4049-fix-buf-ovflow-bgp-dump-ro...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File quagga-CVE-2016-4049-fix-buf-ovflow-bgp-dump-routes.patch of Package quagga.openSUSE_Leap_42.1_Update
Index: quagga-0.99.22.1/bgpd/bgp_dump.c =================================================================== --- quagga-0.99.22.1.orig/bgpd/bgp_dump.c +++ quagga-0.99.22.1/bgpd/bgp_dump.c @@ -271,110 +271,130 @@ bgp_dump_routes_index_table(struct bgp * } -/* Runs under child process. */ -static unsigned int -bgp_dump_routes_func (int afi, int first_run, unsigned int seq) +static struct bgp_info * +bgp_dump_route_node_record (int afi, struct bgp_node *rn, struct bgp_info *info, unsigned int seq) { struct stream *obuf; - 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); + size_t sizep; + size_t endp; obuf = bgp_dump_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)) + /* MRT header */ + if (afi == AFI_IP) { - if(!rn->info) - continue; - - stream_reset(obuf); - - /* MRT header */ - 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); + } #ifdef HAVE_IPV6 - else if (afi == AFI_IP6) - { - bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST); - } + else if (afi == AFI_IP6) + { + bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_RIB_IPV6_UNICAST); + } #endif /* HAVE_IPV6 */ + /* Sequence number */ + stream_putl(obuf, seq); - /* Sequence number */ - stream_putl(obuf, seq); - - /* Prefix length */ - stream_putc (obuf, rn->p.prefixlen); + /* Prefix length */ + stream_putc (obuf, rn->p.prefixlen); - /* Prefix */ - if (afi == AFI_IP) - { - /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ - stream_write(obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8); - } + /* Prefix */ + if (afi == AFI_IP) + { + /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ + stream_write(obuf, (u_char *)&rn->p.u.prefix4, (rn->p.prefixlen+7)/8); + } #ifdef HAVE_IPV6 - else if (afi == AFI_IP6) - { - /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ - stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8); - } + else if (afi == AFI_IP6) + { + /* We'll dump only the useful bits (those not 0), but have to align on 8 bits */ + stream_write (obuf, (u_char *)&rn->p.u.prefix6, (rn->p.prefixlen+7)/8); + } #endif /* HAVE_IPV6 */ - /* Save where we are now, so we can overwride the entry count later */ - int sizep = stream_get_endp(obuf); + /* Save where we are now, so we can overwride the entry count later */ + sizep = stream_get_endp(obuf); - /* Entry count */ - uint16_t entry_count = 0; + /* Entry count */ + uint16_t entry_count = 0; - /* Entry count, note that this is overwritten later */ - stream_putw(obuf, 0); + /* Entry count, note that this is overwritten later */ + stream_putw(obuf, 0); - for (info = rn->info; info; info = info->next) - { - entry_count++; + endp = stream_get_endp(obuf); + for (; info; info = info->next) + { + size_t cur_endp; - /* Peer index */ - stream_putw(obuf, info->peer->table_dump_index); + /* Peer index */ + stream_putw(obuf, info->peer->table_dump_index); - /* Originated */ + /* Originated */ #ifdef HAVE_CLOCK_MONOTONIC stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime)); #else - stream_putl (obuf, info->uptime); + stream_putl (obuf, info->uptime); #endif /* HAVE_CLOCK_MONOTONIC */ - /* Dump attribute. */ - /* Skip prefix & AFI/SAFI for MP_NLRI */ - bgp_dump_routes_attr (obuf, info->attr, &rn->p); - } + /* Dump attribute. */ + /* Skip prefix & AFI/SAFI for MP_NLRI */ + bgp_dump_routes_attr (obuf, info->attr, &rn->p); - /* Overwrite the entry count, now that we know the right number */ - stream_putw_at (obuf, sizep, entry_count); + 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; + } - seq++; + entry_count++; + endp = cur_endp; + } - bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2); - fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp); + /* Overwrite the entry count, now that we know the right number */ + stream_putw_at (obuf, sizep, entry_count); + bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2); + 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); @@ -854,8 +874,8 @@ bgp_dump_init (void) memset (&bgp_dump_updates, 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_HEADER_SIZE); + bgp_dump_obuf = stream_new ((BGP_MAX_PACKET_SIZE << 1) + + BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE); install_node (&bgp_dump_node, config_write_bgp_dump);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor