summaryrefslogtreecommitdiffstats
path: root/eigrpd
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2021-04-26 17:20:57 +0200
committerMark Stapp <mjs@voltanet.io>2021-04-26 17:20:57 +0200
commitbb46c2d1ff22108ce65d266f65b9068cf5f0677a (patch)
tree1b5559b358a7139fa175a3b104aa82f6bf00a2ff /eigrpd
parentMerge pull request #8373 from mjstapp/fix_ospf_timeval_dump (diff)
downloadfrr-bb46c2d1ff22108ce65d266f65b9068cf5f0677a.tar.xz
frr-bb46c2d1ff22108ce65d266f65b9068cf5f0677a.zip
eigrpd: validate TLV lengths
Check that incoming TLVS a) don't overrun the incoming packet, b) don't underrun the required size for the type of TLV. Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to 'eigrpd')
-rw-r--r--eigrpd/eigrp_hello.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c
index 13a2c4206..e3680b31a 100644
--- a/eigrpd/eigrp_hello.c
+++ b/eigrpd/eigrp_hello.c
@@ -125,6 +125,10 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
struct eigrp *eigrp = nbr->ei->eigrp;
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 */
nbr->K1 = param->K1;
nbr->K2 = param->K2;
@@ -194,13 +198,22 @@ eigrp_hello_authentication_decode(struct stream *s,
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,
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(
s, (struct TLV_SHA256_Authentication_Type *)tlv_header,
nbr, EIGRP_AUTH_BASIC_HELLO_FLAG);
+ }
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;
+ /* Validate TLV length */
+ if (tlv->length < sizeof(struct TLV_Software_Type))
+ return;
+
nbr->os_rel_major = version->vender_major;
nbr->os_rel_minor = version->vender_minor;
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 *)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 received_ip = param->neighbor_ip;
@@ -346,6 +367,10 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
type = ntohs(tlv_header->type);
length = ntohs(tlv_header->length);
+ /* Validate length against packet size */
+ if (length > size)
+ return;
+
if ((length > 0) && (length <= size)) {
if (IS_DEBUG_EIGRP_PACKET(0, RECV))
zlog_debug(