diff options
author | tonnerre <tonnerre@pkgsrc.org> | 2008-05-13 22:30:47 +0000 |
---|---|---|
committer | tonnerre <tonnerre@pkgsrc.org> | 2008-05-13 22:30:47 +0000 |
commit | 849a884778c317fa1a9adf1152368ad8f6ce0f77 (patch) | |
tree | 9243374d9dcec1524770c127f0f3ffea81dcb9fe /net/quagga | |
parent | c12369e3f48e7c5403eeaee43f1e41668fdf2fa2 (diff) | |
download | pkgsrc-849a884778c317fa1a9adf1152368ad8f6ce0f77.tar.gz |
Add patch for CVE-2007-1995 for stable quagga (NLRI attributes denial of
service).
Diffstat (limited to 'net/quagga')
-rw-r--r-- | net/quagga/Makefile | 3 | ||||
-rw-r--r-- | net/quagga/distinfo | 4 | ||||
-rw-r--r-- | net/quagga/patches/patch-ab | 178 | ||||
-rw-r--r-- | net/quagga/patches/patch-ac | 15 |
4 files changed, 198 insertions, 2 deletions
diff --git a/net/quagga/Makefile b/net/quagga/Makefile index 18613f18012..a108336a96d 100644 --- a/net/quagga/Makefile +++ b/net/quagga/Makefile @@ -1,8 +1,9 @@ -# $NetBSD: Makefile,v 1.30 2007/09/07 22:07:31 jlam Exp $ +# $NetBSD: Makefile,v 1.31 2008/05/13 22:30:47 tonnerre Exp $ # Based on KAME Id: Makefile,v 1.1.2.1.2.1.10.2 1999/01/05 11:03:50 itojun Exp # DISTNAME= quagga-0.98.6 +PKGREVISION= 1 CATEGORIES= net MASTER_SITES= http://www.quagga.net/download/ diff --git a/net/quagga/distinfo b/net/quagga/distinfo index 9fe9af0a19b..823e7ae8d31 100644 --- a/net/quagga/distinfo +++ b/net/quagga/distinfo @@ -1,6 +1,8 @@ -$NetBSD: distinfo,v 1.9 2006/06/05 19:28:25 gdt Exp $ +$NetBSD: distinfo,v 1.10 2008/05/13 22:30:47 tonnerre Exp $ SHA1 (quagga-0.98.6.tar.gz) = 2234d1235f504e9dc5865cc8d5fd4e250bf43ed5 RMD160 (quagga-0.98.6.tar.gz) = e15cd93b5d321660d7e29fc27174352967342879 Size (quagga-0.98.6.tar.gz) = 2019992 bytes SHA1 (patch-aa) = 507d9cccd719e31d0710425858a80cef1215093d +SHA1 (patch-ab) = 3165bb9d31ea7a3a3231e3fe3a0c374ef7b98f00 +SHA1 (patch-ac) = 401c64dd7588ca4736079ecd796deaff6a45d447 diff --git a/net/quagga/patches/patch-ab b/net/quagga/patches/patch-ab new file mode 100644 index 00000000000..e0e8810fbd4 --- /dev/null +++ b/net/quagga/patches/patch-ab @@ -0,0 +1,178 @@ +$NetBSD: patch-ab,v 1.3 2008/05/13 22:30:47 tonnerre Exp $ + +--- bgpd/bgp_attr.c ++++ bgpd/bgp_attr.c +@@ -39,7 +39,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + #include "bgpd/bgp_ecommunity.h" + + /* Attribute strings for logging. */ +-struct message attr_str [] = ++static struct message attr_str [] = + { + { BGP_ATTR_ORIGIN, "ORIGIN" }, + { BGP_ATTR_AS_PATH, "AS_PATH" }, +@@ -58,6 +58,7 @@ struct message attr_str [] = + { BGP_ATTR_MP_UNREACH_NLRI, "MP_UNREACH_NLRI" }, + { 0, NULL } + }; ++int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]); + + struct hash *cluster_hash; + +@@ -922,24 +923,30 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, + { + u_int16_t afi; + u_char safi; +- u_char snpa_num; +- u_char snpa_len; +- u_char *lim; + bgp_size_t nlri_len; ++ size_t start; + int ret; + struct stream *s; + + /* Set end of packet. */ +- s = peer->ibuf; +- lim = stream_pnt (s) + length; +- ++ s = BGP_INPUT(peer); ++ start = stream_get_getp(s); ++ ++ /* safe to read statically sized header? */ ++#define BGP_MP_REACH_MIN_SIZE 5 ++ if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE)) ++ return -1; ++ + /* Load AFI, SAFI. */ + afi = stream_getw (s); + safi = stream_getc (s); + + /* Get nexthop length. */ + attr->mp_nexthop_len = stream_getc (s); +- ++ ++ if (STREAM_READABLE(s) < attr->mp_nexthop_len) ++ return -1; ++ + /* Nexthop length check. */ + switch (attr->mp_nexthop_len) + { +@@ -986,31 +993,28 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, + break; + } + +- snpa_num = stream_getc (s); +- +- while (snpa_num--) +- { +- snpa_len = stream_getc (s); +- stream_forward (s, (snpa_len + 1) >> 1); +- } ++ if (!STREAM_READABLE(s)) ++ return -1; ++ ++ { ++ u_char val; ++ if ((val = stream_getc (s))) ++ zlog_warn ("%s sent non-zero value, %u, for defunct SNPA-length field", ++ peer->host, val); ++ } ++ ++ /* must have nrli_len, what is left of the attribute */ ++ nlri_len = length - (stream_get_getp(s) - start); ++ if ((!nlri_len) || (nlri_len > STREAM_READABLE(s))) ++ return -1; + +- /* If peer is based on old draft-00. I read NLRI length from the +- packet. */ +- if (peer->version == BGP_VERSION_MP_4_DRAFT_00) +- { +- bgp_size_t nlri_total_len; +- nlri_total_len = stream_getw (s); +- } +- +- nlri_len = lim - stream_pnt (s); +- + if (safi != BGP_SAFI_VPNV4) + { + ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len); + if (ret < 0) + return -1; + } +- ++ + mp_update->afi = afi; + mp_update->safi = safi; + mp_update->nlri = stream_pnt (s); +@@ -1023,24 +1027,26 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, + + /* Multiprotocol unreachable parse */ + int +-bgp_mp_unreach_parse (struct peer *peer, int length, ++bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length, + struct bgp_nlri *mp_withdraw) + { + struct stream *s; + u_int16_t afi; + u_char safi; +- u_char *lim; + u_int16_t withdraw_len; + int ret; + + s = peer->ibuf; +- lim = stream_pnt (s) + length; + ++#define BGP_MP_UNREACH_MIN_SIZE 3 ++ if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE)) ++ return -1; ++ + afi = stream_getw (s); + safi = stream_getc (s); +- +- withdraw_len = lim - stream_pnt (s); +- ++ ++ withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE; ++ + if (safi != BGP_SAFI_VPNV4) + { + ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), withdraw_len); +@@ -1271,13 +1277,23 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, + + /* If error occured immediately return to the caller. */ + if (ret < 0) +- return ret; ++ { ++ zlog (peer->log, LOG_WARNING, ++ "%s: Attribute %s, parse error", ++ peer->host, ++ LOOKUP (attr_str, type)); ++ bgp_notify_send (peer, ++ BGP_NOTIFY_UPDATE_ERR, ++ BGP_NOTIFY_UPDATE_MAL_ATTR); ++ return ret; ++ } + + /* Check the fetched length. */ + if (BGP_INPUT_PNT (peer) != attr_endp) + { + zlog (peer->log, LOG_WARNING, +- "%s BGP attribute fetch error", peer->host); ++ "%s: BGP attribute %s, fetch error", ++ peer->host, LOOKUP (attr_str, type)); + bgp_notify_send (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); +@@ -1289,7 +1305,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, + if (BGP_INPUT_PNT (peer) != endp) + { + zlog (peer->log, LOG_WARNING, +- "%s BGP attribute length mismatch", peer->host); ++ "%s BGP attribute %s, length mismatch", ++ peer->host, LOOKUP (attr_str, type)); + bgp_notify_send (peer, + BGP_NOTIFY_UPDATE_ERR, + BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); +diff --git a/doc/quagga.info b/doc/quagga.info +diff --git a/lib/stream.h b/lib/stream.h +index f7a94ea..a85e413 100644 diff --git a/net/quagga/patches/patch-ac b/net/quagga/patches/patch-ac new file mode 100644 index 00000000000..10dfa797722 --- /dev/null +++ b/net/quagga/patches/patch-ac @@ -0,0 +1,15 @@ +$NetBSD: patch-ac,v 1.3 2008/05/13 22:30:47 tonnerre Exp $ + +--- lib/stream.h ++++ lib/stream.h +@@ -59,7 +59,9 @@ struct stream_fifo + #define STREAM_SIZE(S) ((S)->size) + #define STREAM_REMAIN(S) ((S)->size - (S)->putp) + #define STREAM_DATA(S) ((S)->data) +- ++/* number of bytes still to be read */ ++#define STREAM_READABLE(S) ((S)->endp - (S)->getp) ++ + /* Stream prototypes. */ + struct stream *stream_new (size_t); + void stream_free (struct stream *); |