Skip to content

Commit

Permalink
ospfd: Correct Opaque LSA Extended Link parser
Browse files Browse the repository at this point in the history
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.

Co-authored-by: Iggy Frankovic <[email protected]>
Signed-off-by: Olivier Dugeon <[email protected]>
  • Loading branch information
odd22 and Iggy Frankovic committed Apr 5, 2024
1 parent 6b84541 commit 344fb4b
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions ospfd/ospf_te.c
Original file line number Diff line number Diff line change
Expand Up @@ -2753,6 +2753,13 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)

/* Initialize TLV browsing */
len = TLV_BODY_SIZE(&ext->header) - EXT_TLV_LINK_SIZE;
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;
}

tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
+ EXT_TLV_LINK_SIZE);
for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
Expand All @@ -2762,6 +2769,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)
Expand All @@ -2788,6 +2797,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)
Expand Down Expand Up @@ -2817,6 +2828,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,
Expand Down

0 comments on commit 344fb4b

Please sign in to comment.