SHA256
1
0
forked from pool/frr
frr/0022-ospfd-Correct-Opaque-LSA-Extended-parser.patch
Dirk Mueller 26e7e54960 Accepting request 1178686 from home:mtomaschewski:branches:network
- Apply upstream fix solving ospfd denial of service via get_edge()
  function returning a NULL pointer (CVE-2024-34088,bsc#1223786,
  gh#FRRouting/frr#16088).
  [+ 0023-ospfd-protect-call-to-get_edge-in-ospf_te.c.patch]
- Apply upstream fix solving ospfd buffer overflow and daemon crash
  in ospf_te_parse_ext_link for OSPF LSA packets during an attempt
  to read Segment Routing Adjacency SID subTLVs (CVE-2024-31951,
  bsc#1222528,gh#FRRouting/frr#16088).
  [+ 0022-ospfd-Correct-Opaque-LSA-Extended-parser.patch]
- Apply upstream fix solving ospfd buffer overflow and daemon crash
  in RI parsing with OSPF TE (CVE-2024-31950,bsc#1222526,
  gh#FRRouting/frr#16088).
  [+ 0021-ospfd-Solved-crash-in-RI-parsing-with-OSPF-TE.patch]

OBS-URL: https://build.opensuse.org/request/show/1178686
OBS-URL: https://build.opensuse.org/package/show/network/frr?expand=0&rev=67
2024-06-11 07:47:26 +00:00

110 lines
4.1 KiB
Diff

From 4e70b09f24b72fbb27ff5eda63393bfd2a72ef37 Mon Sep 17 00:00:00 2001
From: Olivier Dugeon <olivier.dugeon@orange.com>
Date: Fri, 5 Apr 2024 12:57:11 +0200
Upstream: yes
References: CVE-2024-31951,bsc#1222528,gh#FRRouting/frr#16088
Subject: [PATCH 2/3] ospfd: Correct Opaque LSA Extended parser
Iggy Frankovic discovered another ospfd crash when performing fuzzing of OSPF
LSA packets. The crash occurs in ospf_te_parse_ext_link() function when
attemping to read Segment Routing Adjacency SID subTLVs. The original code
doesn't check if the size of the Extended Link TLVs and subTLVs have the correct
length. In presence of erronous LSA, this will cause a buffer overflow and ospfd
crashes.
This patch introduces new verification of the subTLVs size for Extended Link
TLVs and subTLVs. Similar check has been also introduced for the Extended
Prefix TLV.
Co-authored-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
(cherry picked from commit 5557a289acdaeec8cc63ffc97b5c2abf6dee7b3a)
---
ospfd/ospf_te.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index 885b915585..23a1b181ec 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -2647,6 +2647,7 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa)
struct ext_tlv_prefix *ext;
struct ext_subtlv_prefix_sid *pref_sid;
uint32_t label;
+ uint16_t len, size;
/* Get corresponding Subnet from Link State Data Base */
ext = (struct ext_tlv_prefix *)TLV_HDR_TOP(lsa->data);
@@ -2668,6 +2669,18 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa)
ote_debug(" |- Process Extended Prefix LSA %pI4 for subnet %pFX",
&lsa->data->id, &pref);
+ /*
+ * Check Extended Prefix TLV size against LSA size
+ * as only one TLV is allowed per LSA
+ */
+ len = TLV_BODY_SIZE(&ext->header);
+ size = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE);
+ if (len != size || len <= 0) {
+ ote_debug(" |- Wrong TLV size: %u instead of %u",
+ (uint32_t)len, (uint32_t)size);
+ return -1;
+ }
+
/* Initialize TLV browsing */
ls_pref = subnet->ls_pref;
pref_sid = (struct ext_subtlv_prefix_sid *)((char *)(ext) + TLV_HDR_SIZE
@@ -2778,8 +2791,20 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
ote_debug(" |- Process Extended Link LSA %pI4 for edge %pI4",
&lsa->data->id, &edge->attributes->standard.local);
- /* Initialize TLV browsing */
- len = TLV_BODY_SIZE(&ext->header) - EXT_TLV_LINK_SIZE;
+ /*
+ * Check Extended Link TLV size against LSA size
+ * as only one TLV is allowed per LSA
+ */
+ len = TLV_BODY_SIZE(&ext->header);
+ i = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE);
+ if (len != i || len <= 0) {
+ ote_debug(" |- Wrong TLV size: %u instead of %u",
+ (uint32_t)len, (uint32_t)i);
+ return -1;
+ }
+
+ /* Initialize subTLVs browsing */
+ len -= EXT_TLV_LINK_SIZE;
tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
+ EXT_TLV_LINK_SIZE);
for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
@@ -2789,6 +2814,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
switch (ntohs(tlvh->type)) {
case EXT_SUBTLV_ADJ_SID:
+ if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_ADJ_SID_SIZE)
+ break;
adj = (struct ext_subtlv_adj_sid *)tlvh;
label = CHECK_FLAG(adj->flags,
EXT_SUBTLV_LINK_ADJ_SID_VFLG)
@@ -2815,6 +2842,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
break;
case EXT_SUBTLV_LAN_ADJ_SID:
+ if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_LAN_ADJ_SID_SIZE)
+ break;
ladj = (struct ext_subtlv_lan_adj_sid *)tlvh;
label = CHECK_FLAG(ladj->flags,
EXT_SUBTLV_LINK_ADJ_SID_VFLG)
@@ -2844,6 +2873,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
break;
case EXT_SUBTLV_RMT_ITF_ADDR:
+ if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_RMT_ITF_ADDR_SIZE)
+ break;
rmt = (struct ext_subtlv_rmt_itf_addr *)tlvh;
if (CHECK_FLAG(atr->flags, LS_ATTR_NEIGH_ADDR)
&& IPV4_ADDR_SAME(&atr->standard.remote,
--
2.35.3