Dirk Mueller
26e7e54960
- 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
110 lines
4.1 KiB
Diff
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
|
|
|