17658177 problem in SERVICE/QUAGGA s11u1-sru
authorBrian Utterback <brian.utterback@oracle.com>
Fri, 25 Oct 2013 14:37:51 -0700
branchs11u1-sru
changeset 2952 e67c9321ec34
parent 2950 465ccac0860e
child 2954 33df57f08b3e
17658177 problem in SERVICE/QUAGGA 17658165 mitigate CVE-2013-0149 in quagga
components/quagga/patches/12-cve-2013-0149.patch
components/quagga/patches/14-cve-2013-2236.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/12-cve-2013-0149.patch	Fri Oct 25 14:37:51 2013 -0700
@@ -0,0 +1,67 @@
+This patch may be removed when Quagga is upgraded to at least 
+version 0.99.22.4 or 0.99.23
+
+
+From 23cd8fb7133befdb84b3a918f7b2f6147161ac6e Mon Sep 17 00:00:00 2001
+From: David Lamparter <[email protected]>
+Date: Fri, 2 Aug 2013 07:27:53 +0000
+Subject: [PATCH] ospfd: protect vs. VU#229804 (malformed Router-LSA)
+
+VU#229804 reports that, by injecting Router LSAs with the Advertising
+Router ID different from the Link State ID, OSPF implementations can be
+tricked into retaining and using invalid information.
+
+Quagga is not vulnerable to this because it looks up Router LSAs by
+(Router-ID, LS-ID) pair.  The relevant code is in ospf_lsa.c l.3140.
+Note the double "id" parameter at the end.
+
+Still, we can provide an improvement here by discarding such malformed
+LSAs and providing a warning to the administrator.  While we cannot
+prevent such malformed LSAs from entering the OSPF domain, we can
+certainly try to limit their distribution.
+
+cf. http://www.kb.cert.org/vuls/id/229804 for the vulnerability report.
+This issue is a specification issue in the OSPF protocol that was
+discovered by Dr. Gabi Nakibly.
+
+Reported-by: CERT Coordination Center <[email protected]>
+Signed-off-by: David Lamparter <[email protected]>
+---
+ ospfd/ospf_packet.c |   21 +++++++++++++++++++++
+ 1 files changed, 21 insertions(+), 0 deletions(-)
+
+diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
+index 37223fb..ab68bf0 100644
+--- ospfd/ospf_packet.c
++++ ospfd/ospf_packet.c
+@@ -1823,6 +1823,27 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
+ 	    DISCARD_LSA (lsa,2);
+ 	  }
+ 
++      /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
++      if (lsa->data->type == OSPF_ROUTER_LSA)
++	if (!IPV4_ADDR_SAME(&lsa->data->id, &lsa->data->adv_router))
++	  {
++	    char buf1[INET_ADDRSTRLEN];
++	    char buf2[INET_ADDRSTRLEN];
++	    char buf3[INET_ADDRSTRLEN];
++
++	    zlog_err("Incoming Router-LSA from %s with "
++		      "Adv-ID[%s] != LS-ID[%s]",
++		      inet_ntop (AF_INET, &ospfh->router_id,
++				 buf1, INET_ADDRSTRLEN),
++		      inet_ntop (AF_INET, &lsa->data->id,
++				 buf2, INET_ADDRSTRLEN),
++		      inet_ntop (AF_INET, &lsa->data->adv_router,
++				 buf3, INET_ADDRSTRLEN));
++	    zlog_err("OSPF domain compromised by attack or corruption. "
++		     "Verify correct operation of -ALL- OSPF routers.");
++	    DISCARD_LSA (lsa, 0);
++	  }
++
+       /* Find the LSA in the current database. */
+ 
+       current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
+-- 
+1.7.2.5
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/quagga/patches/14-cve-2013-2236.patch	Fri Oct 25 14:37:51 2013 -0700
@@ -0,0 +1,114 @@
+This patch may be removed once Quagga is updated to 0.99.22.2 or
+later.
+
+
+From c51443f4aa6b7f0b0d6ad5409ad7d4b215092443 Mon Sep 17 00:00:00 2001
+From: David Lamparter <[email protected]>
+Date: Mon, 8 Jul 2013 23:05:28 +0200
+Subject: [PATCH] ospfd: CVE-2013-2236, stack overrun in apiserver
+
+the OSPF API-server (exporting the LSDB and allowing announcement of
+Opaque-LSAs) writes past the end of fixed on-stack buffers.  This leads
+to an exploitable stack overflow.
+
+For this condition to occur, the following two conditions must be true:
+- Quagga is configured with --enable-opaque-lsa
+- ospfd is started with the "-a" command line option
+
+If either of these does not hold, the relevant code is not executed and
+the issue does not get triggered.
+
+Since the issue occurs on receiving large LSAs (larger than 1488 bytes),
+it is possible for this to happen during normal operation of a network.
+In particular, if there is an OSPF router with a large number of
+interfaces, the Router-LSA of that router may exceed 1488 bytes and
+trigger this, leading to an ospfd crash.
+
+For an attacker to exploit this, s/he must be able to inject valid LSAs
+into the OSPF domain.  Any best-practice protection measure (using
+crypto authentication, restricting OSPF to internal interfaces, packet
+filtering protocol 89, etc.) will prevent exploitation.  On top of that,
+remote (not on an OSPF-speaking network segment) attackers will have
+difficulties bringing up the adjacency needed to inject a LSA.
+
+This patch only performs minimal changes to remove the possibility of a
+stack overrun.  The OSPF API in general is quite ugly and needs a
+rewrite.
+
+Reported-by: Ricky Charlet <[email protected]>
+Cc: Florian Weimer <[email protected]>
+Signed-off-by: David Lamparter <[email protected]>
+---
+ ospfd/ospf_api.c |   25 ++++++++++++++++++-------
+ 1 files changed, 19 insertions(+), 7 deletions(-)
+
+--- ospfd/ospf_api.c
++++ ospfd/ospf_api.c
+@@ -21,6 +21,7 @@
+  */
+ 
+ #include <zebra.h>
++#include <stddef.h>
+ 
+ #ifdef SUPPORT_OSPF_API
+ #ifndef HAVE_OPAQUE_LSA
+@@ -472,6 +473,9 @@ new_msg_register_event (u_int32_t seqnum
+   emsg->filter.typemask = htons (filter->typemask);
+   emsg->filter.origin = filter->origin;
+   emsg->filter.num_areas = filter->num_areas;
++  if (len > sizeof (buf))
++    len = sizeof(buf);
++  /* API broken - missing memcpy to fill data */
+   return msg_new (MSG_REGISTER_EVENT, emsg, seqnum, len);
+ }
+ 
+@@ -488,6 +492,9 @@ new_msg_sync_lsdb (u_int32_t seqnum, str
+   smsg->filter.typemask = htons (filter->typemask);
+   smsg->filter.origin = filter->origin;
+   smsg->filter.num_areas = filter->num_areas;
++  if (len > sizeof (buf))
++    len = sizeof(buf);
++  /* API broken - missing memcpy to fill data */
+   return msg_new (MSG_SYNC_LSDB, smsg, seqnum, len);
+ }
+ 
+@@ -501,13 +508,15 @@ new_msg_originate_request (u_int32_t seq
+   int omsglen;
+   char buf[OSPF_API_MAX_MSG_SIZE];
+ 
+-  omsglen = sizeof (struct msg_originate_request) - sizeof (struct lsa_header)
+-    + ntohs (data->length);
+-
+   omsg = (struct msg_originate_request *) buf;
+   omsg->ifaddr = ifaddr;
+   omsg->area_id = area_id;
+-  memcpy (&omsg->data, data, ntohs (data->length));
++
++  omsglen = ntohs (data->length);
++  if (omsglen > sizeof (buf) - offsetof (struct msg_originate_request, data))
++    omsglen = sizeof (buf) - offsetof (struct msg_originate_request, data);
++  memcpy (&omsg->data, data, omsglen);
++  omsglen += sizeof (struct msg_originate_request) - sizeof (struct lsa_header);
+ 
+   return msg_new (MSG_ORIGINATE_REQUEST, omsg, seqnum, omsglen);
+ }
+@@ -627,13 +636,16 @@ new_msg_lsa_change_notify (u_char msgtyp
+   assert (data);
+ 
+   nmsg = (struct msg_lsa_change_notify *) buf;
+-  len = ntohs (data->length) + sizeof (struct msg_lsa_change_notify)
+-    - sizeof (struct lsa_header);
+   nmsg->ifaddr = ifaddr;
+   nmsg->area_id = area_id;
+   nmsg->is_self_originated = is_self_originated;
+   memset (&nmsg->pad, 0, sizeof (nmsg->pad));
+-  memcpy (&nmsg->data, data, ntohs (data->length));
++
++  len = ntohs (data->length);
++  if (len > sizeof (buf) - offsetof (struct msg_lsa_change_notify, data))
++    len = sizeof (buf) - offsetof (struct msg_lsa_change_notify, data);
++  memcpy (&nmsg->data, data, len);
++  len += sizeof (struct msg_lsa_change_notify) - sizeof (struct lsa_header);
+ 
+   return msg_new (msgtype, nmsg, seqnum, len);
+ }