switch(tlv_type) {
case LS_OPAQUE_TE_TLV_LINK:
- while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) {
+ while (tlv_length != 0) {
if (tlv_length < 4) {
ND_PRINT("\n\t Remaining TLV length %u < 4",
tlv_length);
subtlv_type,
subtlv_length);
+ if (tlv_length < subtlv_length) {
+ ND_PRINT("\n\t Remaining TLV length %u < %u",
+ tlv_length + 4, subtlv_length + 4);
+ return -1;
+ }
ND_TCHECK_LEN(tptr, subtlv_length);
switch(subtlv_type) {
case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
if (subtlv_length%4 != 0)
subtlv_length+=4-(subtlv_length%4);
+ if (tlv_length < subtlv_length) {
+ ND_PRINT("\n\t Remaining TLV length %u < %u",
+ tlv_length + 4, subtlv_length + 4);
+ return -1;
+ }
tlv_length-=subtlv_length;
tptr+=subtlv_length;
/* in OSPF everything has to be 32-bit aligned, including TLVs */
if (tlv_length%4 != 0)
tlv_length+=4-(tlv_length%4);
+ if (tlv_length > ls_length) {
+ ND_PRINT("\n\t Bogus padded length %u > %u", tlv_length,
+ ls_length);
+ return -1;
+ }
ls_length-=tlv_length;
tptr+=tlv_length;
}
case LS_OPAQUE_TYPE_RI:
tptr = (const uint8_t *)(lsap->lsa_un.un_ri_tlv);
- while (ls_length != 0) {
+ int ls_length_remaining = ls_length;
+ while (ls_length_remaining != 0) {
ND_TCHECK_4(tptr);
- if (ls_length < 4) {
- ND_PRINT("\n\t Remaining LS length %u < 4", ls_length);
+ if (ls_length_remaining < 4) {
+ ND_PRINT("\n\t Remaining LS length %u < 4", ls_length_remaining);
return(ls_end);
}
tlv_type = GET_BE_U_2(tptr);
tlv_length = GET_BE_U_2(tptr + 2);
tptr+=4;
- ls_length-=4;
+ ls_length_remaining-=4;
ND_PRINT("\n\t %s TLV (%u), length: %u, value: ",
tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type),
tlv_type,
tlv_length);
- if (tlv_length > ls_length) {
- ND_PRINT("\n\t Bogus length %u > %u", tlv_length,
- ls_length);
+ if (tlv_length > ls_length_remaining) {
+ ND_PRINT("\n\t Bogus length %u > remaining LS length %u", tlv_length,
+ ls_length_remaining);
return(ls_end);
}
ND_TCHECK_LEN(tptr, tlv_length);
}
tptr+=tlv_length;
- ls_length-=tlv_length;
+ ls_length_remaining-=tlv_length;
}
break;