On 2018/02/16 19:11, Gleydson Soares wrote:
> > yep, one of these is particularly nasty: use-after-free in a transitive
> > BGP attribute. this is one of those "one update message can kill all
> > quaggas on the internet" bugs.
> 
> i've backported the security patches to -stable

ah sorry for the dup work, I just committed Quagga-2018-1114 fix
to stable before I saw this ..

> potentially severe:
> "bgpd/security: Fix double free of unknown attribute"
> https://www.quagga.net/security/Quagga-2018-1114.txt
> 
> also fixes:
> https://www.quagga.net/security/Quagga-2018-1550.txt
> https://www.quagga.net/security/Quagga-2018-1975.txt 

I skipped those, could pull them across but they're relatively minor.

> the following is not needed for -stable, only affects >1.1.x
> https://www.quagga.net/security/Quagga-2018-0543.txt
> 
> OK?

> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/net/quagga/Makefile,v
> retrieving revision 1.52
> diff -u -p -r1.52 Makefile
> --- Makefile  27 Jun 2016 19:55:48 -0000      1.52
> +++ Makefile  16 Feb 2018 22:07:00 -0000
> @@ -3,7 +3,7 @@
>  COMMENT=     multi-threaded routing daemon
>  
>  DISTNAME=    quagga-1.0.20160315
> -REVISION=    1
> +REVISION=    2
>  CATEGORIES=  net
>  MASTER_SITES=        http://download.savannah.gnu.org/releases/quagga/
>  EXTRACT_SUFX=        .tar.xz
> Index: patches/patch-bgpd_bgp_attr_c
> ===================================================================
> RCS file: patches/patch-bgpd_bgp_attr_c
> diff -N patches/patch-bgpd_bgp_attr_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-bgpd_bgp_attr_c     16 Feb 2018 22:07:00 -0000
> @@ -0,0 +1,71 @@
> +$OpenBSD$
> +
> +Security issue: Quagga-2018-1114
> +See: https://www.quagga.net/security/Quagga-2018-1114.txt
> +
> +Index: bgpd/bgp_attr.c
> +--- bgpd/bgp_attr.c.orig
> ++++ bgpd/bgp_attr.c
> +@@ -186,15 +186,17 @@ cluster_intern (struct cluster_list *cluster)
> + }
> + 
> + void
> +-cluster_unintern (struct cluster_list *cluster)
> ++cluster_unintern (struct cluster_list **cluster)
> + {
> +-  if (cluster->refcnt)
> +-    cluster->refcnt--;
> ++  struct cluster_list *c = *cluster;
> ++  if (c->refcnt)
> ++    c->refcnt--;
> + 
> +-  if (cluster->refcnt == 0)
> ++  if (c->refcnt == 0)
> +     {
> +-      hash_release (cluster_hash, cluster);
> +-      cluster_free (cluster);
> ++      hash_release (cluster_hash, c);
> ++      cluster_free (c);
> ++      *cluster = NULL;
> +     }
> + }
> + 
> +@@ -344,15 +346,18 @@ transit_intern (struct transit *transit)
> + }
> + 
> + void
> +-transit_unintern (struct transit *transit)
> ++transit_unintern (struct transit **transit)
> + {
> +-  if (transit->refcnt)
> +-    transit->refcnt--;
> ++  struct transit *t = *transit;
> ++  
> ++  if (t->refcnt)
> ++    t->refcnt--;
> + 
> +-  if (transit->refcnt == 0)
> ++  if (t->refcnt == 0)
> +     {
> +-      hash_release (transit_hash, transit);
> +-      transit_free (transit);
> ++      hash_release (transit_hash, t);
> ++      transit_free (t);
> ++      *transit = NULL;
> +     }
> + }
> + 
> +@@ -788,11 +793,11 @@ bgp_attr_unintern_sub (struct attr *attr)
> +       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
> +       
> +       if (attr->extra->cluster)
> +-        cluster_unintern (attr->extra->cluster);
> ++        cluster_unintern (&attr->extra->cluster);
> +       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
> +       
> +       if (attr->extra->transit)
> +-        transit_unintern (attr->extra->transit);
> ++        transit_unintern (&attr->extra->transit);
> +     }
> + }
> + 
> Index: patches/patch-bgpd_bgp_attr_h
> ===================================================================
> RCS file: patches/patch-bgpd_bgp_attr_h
> diff -N patches/patch-bgpd_bgp_attr_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-bgpd_bgp_attr_h     16 Feb 2018 22:07:00 -0000
> @@ -0,0 +1,21 @@
> +$OpenBSD$
> +
> +Security issue: Quagga-2018-1114
> +See: https://www.quagga.net/security/Quagga-2018-1114.txt
> +
> +Index: bgpd/bgp_attr.h
> +--- bgpd/bgp_attr.h.orig
> ++++ bgpd/bgp_attr.h
> +@@ -182,10 +182,10 @@ extern unsigned long int attr_unknown_count (void);
> + 
> + /* Cluster list prototypes. */
> + extern int cluster_loop_check (struct cluster_list *, struct in_addr);
> +-extern void cluster_unintern (struct cluster_list *);
> ++extern void cluster_unintern (struct cluster_list **);
> + 
> + /* Transit attribute prototypes. */
> +-void transit_unintern (struct transit *);
> ++void transit_unintern (struct transit **);
> + 
> + /* Below exported for unit-test purposes only */
> + struct bgp_attr_parser_args {
> Index: patches/patch-bgpd_bgp_debug_c
> ===================================================================
> RCS file: patches/patch-bgpd_bgp_debug_c
> diff -N patches/patch-bgpd_bgp_debug_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-bgpd_bgp_debug_c    16 Feb 2018 22:07:00 -0000
> @@ -0,0 +1,91 @@
> +$OpenBSD$
> +
> +Security issue: Quagga-2018-1550
> +See: https://www.quagga.net/security/Quagga-2018-1550.txt
> +
> +Index: bgpd/bgp_debug.c
> +--- bgpd/bgp_debug.c.orig
> ++++ bgpd/bgp_debug.c
> +@@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330
> + #include "log.h"
> + #include "sockunion.h"
> + #include "filter.h"
> ++#include "memory.h"
> + 
> + #include "bgpd/bgpd.h"
> + #include "bgpd/bgp_aspath.h"
> +@@ -69,7 +70,8 @@ const struct message bgp_status_msg[] = 
> +   { Clearing,    "Clearing"    },
> +   { Deleted,     "Deleted"     },
> + };
> +-const int bgp_status_msg_max = BGP_STATUS_MAX;
> ++#define BGP_DEBUG_MSG_MAX(msg) const int msg ## _max = array_size (msg)
> ++BGP_DEBUG_MSG_MAX (bgp_status_msg);
> + 
> + /* BGP message type string. */
> + const char *bgp_type_str[] =
> +@@ -80,7 +82,8 @@ const char *bgp_type_str[] =
> +   "NOTIFICATION",
> +   "KEEPALIVE",
> +   "ROUTE-REFRESH",
> +-  "CAPABILITY"
> ++  "CAPABILITY",
> ++  NULL,
> + };
> + 
> + /* message for BGP-4 Notify */
> +@@ -94,15 +97,15 @@ static const struct message bgp_notify_msg[] = 
> +   { BGP_NOTIFY_CEASE, "Cease"},
> +   { BGP_NOTIFY_CAPABILITY_ERR, "CAPABILITY Message Error"},
> + };
> +-static const int bgp_notify_msg_max = BGP_NOTIFY_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_msg);
> + 
> + static const struct message bgp_notify_head_msg[] = 
> + {
> +   { BGP_NOTIFY_HEADER_NOT_SYNC, "/Connection Not Synchronized"},
> +   { BGP_NOTIFY_HEADER_BAD_MESLEN, "/Bad Message Length"},
> +-  { BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"}
> ++  { BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"},
> + };
> +-static const int bgp_notify_head_msg_max = BGP_NOTIFY_HEADER_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_head_msg);
> + 
> + static const struct message bgp_notify_open_msg[] = 
> + {
> +@@ -115,7 +118,7 @@ static const struct message bgp_notify_open_msg[] = 
> +   { BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, "/Unacceptable Hold Time"}, 
> +   { BGP_NOTIFY_OPEN_UNSUP_CAPBL, "/Unsupported Capability"},
> + };
> +-static const int bgp_notify_open_msg_max = BGP_NOTIFY_OPEN_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_open_msg);
> + 
> + static const struct message bgp_notify_update_msg[] = 
> + {
> +@@ -132,7 +135,7 @@ static const struct message bgp_notify_update_msg[] = 
> +   { BGP_NOTIFY_UPDATE_INVAL_NETWORK, "/Invalid Network Field"},
> +   { BGP_NOTIFY_UPDATE_MAL_AS_PATH, "/Malformed AS_PATH"},
> + };
> +-static const int bgp_notify_update_msg_max = BGP_NOTIFY_UPDATE_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_update_msg);
> + 
> + static const struct message bgp_notify_cease_msg[] =
> + {
> +@@ -146,7 +149,7 @@ static const struct message bgp_notify_cease_msg[] =
> +   { BGP_NOTIFY_CEASE_COLLISION_RESOLUTION, "/Connection collision 
> resolution"},
> +   { BGP_NOTIFY_CEASE_OUT_OF_RESOURCE, "/Out of Resource"},
> + };
> +-static const int bgp_notify_cease_msg_max = BGP_NOTIFY_CEASE_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_cease_msg);
> + 
> + static const struct message bgp_notify_capability_msg[] = 
> + {
> +@@ -155,7 +158,7 @@ static const struct message bgp_notify_capability_msg[
> +   { BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length"},
> +   { BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"},
> + };
> +-static const int bgp_notify_capability_msg_max = BGP_NOTIFY_CAPABILITY_MAX;
> ++BGP_DEBUG_MSG_MAX (bgp_notify_capability_msg);
> + 
> + /* Origin strings. */
> + const char *bgp_origin_str[] = {"i","e","?"};
> Index: patches/patch-bgpd_bgp_packet_c
> ===================================================================
> RCS file: patches/patch-bgpd_bgp_packet_c
> diff -N patches/patch-bgpd_bgp_packet_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-bgpd_bgp_packet_c   16 Feb 2018 22:07:00 -0000
> @@ -0,0 +1,26 @@
> +$OpenBSD$
> +
> +Security issue: Quagga-2018-1975
> +See: https://www.quagga.net/security/Quagga-2018-1975.txt
> +
> +Index: bgpd/bgp_packet.c
> +--- bgpd/bgp_packet.c.orig
> ++++ bgpd/bgp_packet.c
> +@@ -2218,7 +2218,8 @@ bgp_capability_msg_parse (struct peer *peer, u_char *p
> + 
> +   end = pnt + length;
> + 
> +-  while (pnt < end)
> ++  /* XXX: Streamify this */
> ++  for (; pnt < end; pnt += hdr->length + 3)
> +     {      
> +       /* We need at least action, capability code and capability length. */
> +       if (pnt + 3 > end)
> +@@ -2306,7 +2307,6 @@ bgp_capability_msg_parse (struct peer *peer, u_char *p
> +           zlog_warn ("%s unrecognized capability code: %d - ignored",
> +                      peer->host, hdr->code);
> +         }
> +-      pnt += hdr->length + 3;
> +     }
> +   return 0;
> + }

Reply via email to