diff -Nru quagga-0.99.24.1/debian/changelog quagga-0.99.24.1/debian/changelog --- quagga-0.99.24.1/debian/changelog 2017-10-30 14:27:47.000000000 +0000 +++ quagga-0.99.24.1/debian/changelog 2018-02-08 12:18:05.000000000 +0000 @@ -1,3 +1,20 @@ +quagga (0.99.24.1-2ubuntu1.4) xenial-security; urgency=medium + + * SECURITY UPDATE: DoS and possible code execution via double-free + - debian/patches/Quagga-2018-1114.patch: fix double-free in + bgpd/bgp_attr.c, bgpd/bgp_attr.h. + - No CVE number + * SECURITY UPDATE: code-to-string conversion table overrun + - debian/patches/Quagga-2018-1550.patch: limit size in + bgpd/bgp_debug.c. + - No CVE number + * SECURITY UPDATE: hang via invalid OPEN message + - debian/patches/Quagga-2018-1975.patch: fix infinite loop in + bgpd/bgp_packet.c. + - No CVE number + + -- Marc Deslauriers Wed, 07 Feb 2018 07:34:42 -0500 + quagga (0.99.24.1-2ubuntu1.3) xenial-security; urgency=medium * SECURITY UPDATE: DoS via telnet CLI diff -Nru quagga-0.99.24.1/debian/patches/Quagga-2018-1114.patch quagga-0.99.24.1/debian/patches/Quagga-2018-1114.patch --- quagga-0.99.24.1/debian/patches/Quagga-2018-1114.patch 1970-01-01 00:00:00.000000000 +0000 +++ quagga-0.99.24.1/debian/patches/Quagga-2018-1114.patch 2018-02-07 12:33:26.000000000 +0000 @@ -0,0 +1,103 @@ +From e69b535f92eafb599329bf725d9b4c6fd5d7fded Mon Sep 17 00:00:00 2001 +From: Paul Jakma +Date: Sat, 6 Jan 2018 19:52:10 +0000 +Subject: bgpd/security: Fix double free of unknown attribute + +Security issue: Quagga-2018-1114 +See: https://www.quagga.net/security/Quagga-2018-1114.txt + +It is possible for bgpd to double-free an unknown attribute. This can happen +via bgp_update_receive receiving an UPDATE with an invalid unknown attribute. +bgp_update_receive then will call bgp_attr_unintern_sub and bgp_attr_flush, +and the latter may try free an already freed unknown attr. + +* bgpd/bgp_attr.c: (transit_unintern) Take a pointer to the caller's storage + for the (struct transit *), so that transit_unintern can NULL out the + caller's reference if the (struct transit) is freed. + (cluster_unintern) By inspection, appears to have a similar issue. + (bgp_attr_unintern_sub) adjust for above. + +Index: quagga-0.99.24.1/bgpd/bgp_attr.c +=================================================================== +--- quagga-0.99.24.1.orig/bgpd/bgp_attr.c 2018-02-07 07:33:24.502011569 -0500 ++++ quagga-0.99.24.1/bgpd/bgp_attr.c 2018-02-07 07:33:24.474011550 -0500 +@@ -183,15 +183,17 @@ cluster_intern (struct cluster_list *clu + } + + 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; + } + } + +@@ -241,15 +243,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; + } + } + +@@ -660,11 +665,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: quagga-0.99.24.1/bgpd/bgp_attr.h +=================================================================== +--- quagga-0.99.24.1.orig/bgpd/bgp_attr.h 2018-02-07 07:33:24.502011569 -0500 ++++ quagga-0.99.24.1/bgpd/bgp_attr.h 2018-02-07 07:33:24.482011555 -0500 +@@ -174,10 +174,10 @@ extern unsigned long int attr_unknown_co + + /* 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 { diff -Nru quagga-0.99.24.1/debian/patches/Quagga-2018-1550.patch quagga-0.99.24.1/debian/patches/Quagga-2018-1550.patch --- quagga-0.99.24.1/debian/patches/Quagga-2018-1550.patch 1970-01-01 00:00:00.000000000 +0000 +++ quagga-0.99.24.1/debian/patches/Quagga-2018-1550.patch 2018-02-07 12:34:28.000000000 +0000 @@ -0,0 +1,108 @@ +Backport of: + +From 9e5251151894aefdf8e9392a2371615222119ad8 Mon Sep 17 00:00:00 2001 +From: Paul Jakma +Date: Sat, 6 Jan 2018 22:31:52 +0000 +Subject: bgpd/security: debug print of received NOTIFY data can over-read msg + array + +Security issue: Quagga-2018-1550 +See: https://www.quagga.net/security/Quagga-2018-1550.txt + +* bgpd/bgp_debug.c: (struct message) Nearly every one of the NOTIFY + code/subcode message arrays has their corresponding size variables off + by one, as most have 1 as first index. + + This means (bgp_notify_print) can cause mes_lookup to overread the (struct + message) by 1 pointer value if given an unknown index. + + Fix the bgp_notify_..._msg_max variables to use the compiler to calculate + the correct sizes. + +Index: quagga-0.99.24.1/bgpd/bgp_debug.c +=================================================================== +--- quagga-0.99.24.1.orig/bgpd/bgp_debug.c 2018-02-07 07:33:54.862031258 -0500 ++++ quagga-0.99.24.1/bgpd/bgp_debug.c 2018-02-07 07:34:09.726040360 -0500 +@@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Pla + #include "str.h" + #include "log.h" + #include "sockunion.h" ++#include "memory.h" + + #include "bgpd/bgpd.h" + #include "bgpd/bgp_aspath.h" +@@ -68,7 +69,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[] = +@@ -79,7 +81,8 @@ const char *bgp_type_str[] = + "NOTIFICATION", + "KEEPALIVE", + "ROUTE-REFRESH", +- "CAPABILITY" ++ "CAPABILITY", ++ NULL, + }; + + /* message for BGP-4 Notify */ +@@ -93,15 +96,15 @@ static const struct message bgp_notify_m + { 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[] = + { +@@ -114,7 +117,7 @@ static const struct message bgp_notify_o + { 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[] = + { +@@ -131,7 +134,7 @@ static const struct message bgp_notify_u + { 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[] = + { +@@ -145,7 +148,7 @@ static const struct message bgp_notify_c + { 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[] = + { +@@ -154,7 +157,7 @@ static const struct message bgp_notify_c + { 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","?"}; diff -Nru quagga-0.99.24.1/debian/patches/Quagga-2018-1975.patch quagga-0.99.24.1/debian/patches/Quagga-2018-1975.patch --- quagga-0.99.24.1/debian/patches/Quagga-2018-1975.patch 1970-01-01 00:00:00.000000000 +0000 +++ quagga-0.99.24.1/debian/patches/Quagga-2018-1975.patch 2018-02-07 12:34:38.000000000 +0000 @@ -0,0 +1,34 @@ +From ce07207c50a3d1f05d6dd49b5294282e59749787 Mon Sep 17 00:00:00 2001 +From: Paul Jakma +Date: Sat, 6 Jan 2018 21:20:51 +0000 +Subject: bgpd/security: fix infinite loop on certain invalid OPEN messages + +Security issue: Quagga-2018-1975 +See: https://www.quagga.net/security/Quagga-2018-1975.txt + +* bgpd/bgp_packet.c: (bgp_capability_msg_parse) capability parser can infinite + loop due to checks that issue 'continue' without bumping the input + pointer. + +Index: quagga-0.99.24.1/bgpd/bgp_packet.c +=================================================================== +--- quagga-0.99.24.1.orig/bgpd/bgp_packet.c 2018-02-07 07:34:36.938056147 -0500 ++++ quagga-0.99.24.1/bgpd/bgp_packet.c 2018-02-07 07:34:36.938056147 -0500 +@@ -2243,7 +2243,8 @@ bgp_capability_msg_parse (struct peer *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) +@@ -2331,7 +2332,6 @@ bgp_capability_msg_parse (struct peer *p + zlog_warn ("%s unrecognized capability code: %d - ignored", + peer->host, hdr->code); + } +- pnt += hdr->length + 3; + } + return 0; + } diff -Nru quagga-0.99.24.1/debian/patches/series quagga-0.99.24.1/debian/patches/series --- quagga-0.99.24.1/debian/patches/series 2017-10-30 14:25:36.000000000 +0000 +++ quagga-0.99.24.1/debian/patches/series 2018-02-07 12:34:35.000000000 +0000 @@ -9,3 +9,6 @@ CVE-2017-5495-1.patch CVE-2017-5495-2.patch CVE-2017-16227.patch +Quagga-2018-1114.patch +Quagga-2018-1550.patch +Quagga-2018-1975.patch