Merge pull request #8565 from mjstapp/fix_eigrp_tlvs

eigrpd: validate TLV lengths
This commit is contained in:
Donald Sharp 2021-04-26 19:38:01 -04:00 committed by GitHub
commit c0267e5a1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -125,6 +125,10 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
struct eigrp *eigrp = nbr->ei->eigrp; struct eigrp *eigrp = nbr->ei->eigrp;
struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv; struct TLV_Parameter_Type *param = (struct TLV_Parameter_Type *)tlv;
/* First validate TLV length */
if (tlv->length < sizeof(struct TLV_Parameter_Type))
return NULL;
/* copy over the values passed in by the neighbor */ /* copy over the values passed in by the neighbor */
nbr->K1 = param->K1; nbr->K1 = param->K1;
nbr->K2 = param->K2; nbr->K2 = param->K2;
@ -194,13 +198,22 @@ eigrp_hello_authentication_decode(struct stream *s,
md5 = (struct TLV_MD5_Authentication_Type *)tlv_header; md5 = (struct TLV_MD5_Authentication_Type *)tlv_header;
if (md5->auth_type == EIGRP_AUTH_TYPE_MD5) if (md5->auth_type == EIGRP_AUTH_TYPE_MD5) {
/* Validate tlv length */
if (md5->length < sizeof(struct TLV_MD5_Authentication_Type))
return 0;
return eigrp_check_md5_digest(s, md5, nbr, return eigrp_check_md5_digest(s, md5, nbr,
EIGRP_AUTH_BASIC_HELLO_FLAG); EIGRP_AUTH_BASIC_HELLO_FLAG);
else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256) } else if (md5->auth_type == EIGRP_AUTH_TYPE_SHA256) {
/* Validate tlv length */
if (md5->length < sizeof(struct TLV_SHA256_Authentication_Type))
return 0;
return eigrp_check_sha256_digest( return eigrp_check_sha256_digest(
s, (struct TLV_SHA256_Authentication_Type *)tlv_header, s, (struct TLV_SHA256_Authentication_Type *)tlv_header,
nbr, EIGRP_AUTH_BASIC_HELLO_FLAG); nbr, EIGRP_AUTH_BASIC_HELLO_FLAG);
}
return 0; return 0;
} }
@ -223,6 +236,10 @@ static void eigrp_sw_version_decode(struct eigrp_neighbor *nbr,
{ {
struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv; struct TLV_Software_Type *version = (struct TLV_Software_Type *)tlv;
/* Validate TLV length */
if (tlv->length < sizeof(struct TLV_Software_Type))
return;
nbr->os_rel_major = version->vender_major; nbr->os_rel_major = version->vender_major;
nbr->os_rel_minor = version->vender_minor; nbr->os_rel_minor = version->vender_minor;
nbr->tlv_rel_major = version->eigrp_major; nbr->tlv_rel_major = version->eigrp_major;
@ -250,6 +267,10 @@ static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr,
struct TLV_Peer_Termination_type *param = struct TLV_Peer_Termination_type *param =
(struct TLV_Peer_Termination_type *)tlv; (struct TLV_Peer_Termination_type *)tlv;
/* Validate TLV length */
if (tlv->length < sizeof(struct TLV_Peer_Termination_type))
return;
uint32_t my_ip = nbr->ei->address.u.prefix4.s_addr; uint32_t my_ip = nbr->ei->address.u.prefix4.s_addr;
uint32_t received_ip = param->neighbor_ip; uint32_t received_ip = param->neighbor_ip;
@ -346,6 +367,10 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
type = ntohs(tlv_header->type); type = ntohs(tlv_header->type);
length = ntohs(tlv_header->length); length = ntohs(tlv_header->length);
/* Validate length against packet size */
if (length > size)
return;
if ((length > 0) && (length <= size)) { if ((length > 0) && (length <= size)) {
if (IS_DEBUG_EIGRP_PACKET(0, RECV)) if (IS_DEBUG_EIGRP_PACKET(0, RECV))
zlog_debug( zlog_debug(