From 2f18ffc465f312757c212a94023855e0c58e4743 Mon Sep 17 00:00:00 2001
From: Mark Stapp <mjs@cisco.com>
Date: Wed, 11 Mar 2026 14:52:54 -0400
Subject: [PATCH] bgpd: improve packet parsing for EVPN and ENCAP/VNC
Upstream: yes
References: CVE-2026-5107,bsc#1261013,gh#FRRouting/frr#21098,gh#FRRouting/frr#21235

Improve packet validation for EVPN NLRIs and for ENCAP/VNC.

Signed-off-by: Mark Stapp <mjs@cisco.com>
(Backport from commit 7676cad65114aa23adde583d91d9d29e2debd045)

diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index a10686189d..86c71e1a1e 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -4009,6 +4009,14 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
 		return -1;
 	}
 
+	/* Validate ipaddr_len against the NLRI length */
+	if ((psize != 33 + (ipaddr_len / 8)) && (psize != 36 + (ipaddr_len / 8))) {
+		flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+			"%u:%s - Rx EVPN Type-2 NLRI with invalid IP address length %d",
+			peer->bgp->vrf_id, peer->host, ipaddr_len);
+		return -1;
+	}
+
 	if (ipaddr_len) {
 		ipaddr_len /= 8; /* Convert to bytes. */
 		p.prefix.macip_addr.ip.ipa_type = (ipaddr_len == IPV4_MAX_BYTELEN)
@@ -4104,6 +4112,15 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
 
 	/* Get the IP. */
 	ipaddr_len = *pfx++;
+
+	/* Validate */
+	if (psize != 13 + (ipaddr_len / 8)) {
+		flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+			"%u:%s - Rx EVPN Type-3 NLRI with invalid IP address length %d",
+			peer->bgp->vrf_id, peer->host, ipaddr_len);
+		return -1;
+	}
+
 	if (ipaddr_len == IPV4_MAX_BITLEN) {
 		p.prefix.imet_addr.ip.ipa_type = IPADDR_V4;
 		memcpy(&p.prefix.imet_addr.ip.ip.addr, pfx, IPV4_MAX_BYTELEN);
@@ -4161,9 +4178,17 @@ static int process_type4_route(struct peer *peer, afi_t afi, safi_t safi,
 	memcpy(&esi, pfx, ESI_BYTES);
 	pfx += ESI_BYTES;
 
-
 	/* Get the IP. */
 	ipaddr_len = *pfx++;
+
+	/* Validate */
+	if (psize != 19 + (ipaddr_len / 8)) {
+		flog_err(EC_BGP_EVPN_ROUTE_INVALID,
+			"%u:%s - Rx EVPN Type-4 NLRI with invalid IP address length %d",
+			peer->bgp->vrf_id, peer->host, ipaddr_len);
+		return -1;
+	}
+
 	if (ipaddr_len == IPV4_MAX_BITLEN) {
 		memcpy(&vtep_ip, pfx, IPV4_MAX_BYTELEN);
 	} else {
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 95b8582b95..430cb0e34f 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -634,11 +634,20 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri,
 			break;
 
 		case BGP_VNC_SUBTLV_TYPE_RFPOPTION:
+			/* Check for short subtlv: drop */
+			if (pEncap->length < 3)
+				break;
+
+			/* Length of zero not valid */
+			if (pEncap->value[1] == 0)
+				break;
+
 			hop = XCALLOC(MTYPE_BGP_TEA_OPTIONS,
 				      sizeof(struct bgp_tea_options));
 			assert(hop);
 			hop->type = pEncap->value[0];
 			hop->length = pEncap->value[1];
+
 			hop->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE,
 					     pEncap->length - 2);
 			assert(hop->value);
-- 
2.51.0

