diff options
author | Paul Jakma <paul@quagga.net> | 2010-12-05 17:17:26 +0000 |
---|---|---|
committer | Paul Jakma <paul@quagga.net> | 2011-03-21 13:50:56 +0000 |
commit | 0c46638122f10019a12ae9668aec91691cf2e017 (patch) | |
tree | 1302073e844ff46061ebb938bcd218ed9fbb96bf | |
parent | 8f228de7b3f9d6f641c75b27ac7ac6e5862cf804 (diff) |
bgpd/security: CVE-2010-1674 Fix crash due to extended-community parser error
* bgp_attr.c: (bgp_attr_ext_communities) Certain extended-community attrs
can leave attr->flag indicating ext-community is present, even though no
extended-community object has been attached to the attr structure. Thus a
null-pointer dereference can occur later.
(bgp_attr_community) No bug fixed here, but tidy up flow so it has same
form as previous.
Problem and fix thanks to anonymous reporter.
-rw-r--r-- | bgpd/bgp_attr.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 35473651..9c97d6f0 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1214,13 +1214,16 @@ bgp_attr_community (struct peer *peer, bgp_size_t length, attr->community = NULL; return 0; } - else - { - attr->community = - community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length); - stream_forward_getp (peer->ibuf, length); - } + + attr->community = + community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length); + + /* XXX: fix community_parse to use stream API and remove this */ + stream_forward_getp (peer->ibuf, length); + if (!attr->community) + return -1; + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); return 0; @@ -1457,13 +1460,18 @@ bgp_attr_ext_communities (struct peer *peer, bgp_size_t length, { if (attr->extra) attr->extra->ecommunity = NULL; + /* Empty extcomm doesn't seem to be invalid per se */ + return 0; } - else - { - (bgp_attr_extra_get (attr))->ecommunity = - ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length); - stream_forward_getp (peer->ibuf, length); - } + + (bgp_attr_extra_get (attr))->ecommunity = + ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length); + /* XXX: fix ecommunity_parse to use stream API */ + stream_forward_getp (peer->ibuf, length); + + if (!attr->extra->ecommunity) + return -1; + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); return 0; |