# HG changeset patch # User Brian Utterback # Date 1382737071 25200 # Node ID 83313d4990a4245f1d241b6ff8cb2dea81a6064f # Parent 40a8bd356d7623b76d8e7afdb1c58264334ded08 17658177 problem in SERVICE/QUAGGA 17658165 mitigate CVE-2013-0149 in quagga diff -r 40a8bd356d76 -r 83313d4990a4 components/quagga/patches/12-cve-2013-0149.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 +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 +Signed-off-by: David Lamparter +--- + 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 + diff -r 40a8bd356d76 -r 83313d4990a4 components/quagga/patches/14-cve-2013-2236.patch --- /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 +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 +Cc: Florian Weimer +Signed-off-by: David Lamparter +--- + 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 ++#include + + #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); + }