summaryrefslogtreecommitdiff
path: root/ospfd/ospf_sr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospfd/ospf_sr.c')
-rw-r--r--ospfd/ospf_sr.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index d003f3bf7c..3ce177618f 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -954,7 +954,7 @@ static inline void update_adj_sid(struct sr_nhlfe n1, struct sr_nhlfe n2)
*/
/* Extended Link SubTLVs Getter */
-static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
+static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh, size_t size)
{
struct sr_link *srl;
@@ -966,13 +966,20 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
struct tlv_header *sub_tlvh;
uint16_t length = 0, sum = 0, i = 0;
+ /* Check TLV size */
+ if ((ntohs(tlvh->length) > size)
+ || ntohs(tlvh->length) < EXT_TLV_LINK_SIZE) {
+ zlog_warn("Wrong Extended Link TLV size. Abort!");
+ return NULL;
+ }
+
srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
/* Initialize TLV browsing */
length = ntohs(tlvh->length) - EXT_TLV_LINK_SIZE;
sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
+ EXT_TLV_LINK_SIZE);
- for (; sum < length; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
+ for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
switch (ntohs(sub_tlvh->type)) {
case EXT_SUBTLV_ADJ_SID:
adj_sid = (struct ext_subtlv_adj_sid *)sub_tlvh;
@@ -1025,7 +1032,8 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh)
}
/* Extended Prefix SubTLVs Getter */
-static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
+static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh,
+ size_t size)
{
struct sr_prefix *srp;
@@ -1035,13 +1043,20 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh)
struct tlv_header *sub_tlvh;
uint16_t length = 0, sum = 0;
+ /* Check TLV size */
+ if ((ntohs(tlvh->length) > size)
+ || ntohs(tlvh->length) < EXT_TLV_PREFIX_SIZE) {
+ zlog_warn("Wrong Extended Link TLV size. Abort!");
+ return NULL;
+ }
+
srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
/* Initialize TLV browsing */
length = ntohs(tlvh->length) - EXT_TLV_PREFIX_SIZE;
sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
+ EXT_TLV_PREFIX_SIZE);
- for (; sum < length; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
+ for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
switch (ntohs(sub_tlvh->type)) {
case EXT_SUBTLV_PREFIX_SID:
psid = (struct ext_subtlv_prefix_sid *)sub_tlvh;
@@ -1353,7 +1368,7 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
/* Collect Router Information Sub TLVs */
/* Initialize TLV browsing */
- length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
+ length = lsa->size - OSPF_LSA_HEADER_SIZE;
srgb.range_size = 0;
srgb.lower_bound = 0;
@@ -1362,24 +1377,20 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
switch (ntohs(tlvh->type)) {
case RI_SR_TLV_SR_ALGORITHM:
algo = (struct ri_sr_tlv_sr_algorithm *)tlvh;
- sum += TLV_SIZE(tlvh);
break;
case RI_SR_TLV_SRGB_LABEL_RANGE:
ri_srgb = (struct ri_sr_tlv_sid_label_range *)tlvh;
- sum += TLV_SIZE(tlvh);
break;
case RI_SR_TLV_SRLB_LABEL_RANGE:
ri_srlb = (struct ri_sr_tlv_sid_label_range *)tlvh;
- sum += TLV_SIZE(tlvh);
break;
case RI_SR_TLV_NODE_MSD:
msd = ((struct ri_sr_tlv_node_msd *)(tlvh))->value;
- sum += TLV_SIZE(tlvh);
break;
default:
- sum += TLV_SIZE(tlvh);
break;
}
+ sum += TLV_SIZE(tlvh);
}
/* Check if Segment Routing Capabilities has been found */
@@ -1519,7 +1530,7 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa)
struct lsa_header *lsah = lsa->data;
struct sr_link *srl;
- uint16_t length, sum;
+ int length;
osr_debug("SR (%s): Process Extended Link LSA 8.0.0.%u from %pI4",
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
@@ -1546,20 +1557,19 @@ void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa)
}
/* Initialize TLV browsing */
- length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
- sum = 0;
- for (tlvh = TLV_HDR_TOP(lsah); (sum < length) && (tlvh != NULL);
+ length = lsa->size - OSPF_LSA_HEADER_SIZE;
+ for (tlvh = TLV_HDR_TOP(lsah); length > 0 && tlvh;
tlvh = TLV_HDR_NEXT(tlvh)) {
if (ntohs(tlvh->type) == EXT_TLV_LINK) {
/* Got Extended Link information */
- srl = get_ext_link_sid(tlvh);
+ srl = get_ext_link_sid(tlvh, length);
/* Update SID if not null */
if (srl != NULL) {
srl->instance = ntohl(lsah->id.s_addr);
update_ext_link_sid(srn, srl, lsa->flags);
}
}
- sum += TLV_SIZE(tlvh);
+ length -= TLV_SIZE(tlvh);
}
}
@@ -1753,7 +1763,7 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
struct lsa_header *lsah = (struct lsa_header *)lsa->data;
struct sr_prefix *srp;
- uint16_t length, sum;
+ int length;
osr_debug("SR (%s): Process Extended Prefix LSA 7.0.0.%u from %pI4",
__func__, GET_OPAQUE_ID(ntohl(lsah->id.s_addr)),
@@ -1780,20 +1790,19 @@ void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
}
/* Initialize TLV browsing */
- length = ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE;
- sum = 0;
- for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+ length = lsa->size - OSPF_LSA_HEADER_SIZE;
+ for (tlvh = TLV_HDR_TOP(lsah); length > 0 && tlvh;
tlvh = TLV_HDR_NEXT(tlvh)) {
if (ntohs(tlvh->type) == EXT_TLV_LINK) {
/* Got Extended Link information */
- srp = get_ext_prefix_sid(tlvh);
+ srp = get_ext_prefix_sid(tlvh, length);
/* Update SID if not null */
if (srp != NULL) {
srp->instance = ntohl(lsah->id.s_addr);
update_ext_prefix_sid(srn, srp);
}
}
- sum += TLV_SIZE(tlvh);
+ length -= TLV_SIZE(tlvh);
}
}