Commit 87d14fb8bd for frr

commit 87d14fb8bde6a79cdb252666ebef49ca234454dd
Author: Nageswara Soma <nsoma@cisco.com>
Date:   Wed Apr 29 23:27:24 2026 -0700

    bgpd: parse dynamic FQDN capability atomically

    Decode the dynamic FQDN SET payload into temporary
    allocations. Replace the stored peer values only after
    both fields pass validation. Free the temporary
    hostname when domain validation fails.

    Signed-off-by: Nageswara Soma <nsoma@cisco.com>

diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 5e14c6199b..9bb5fd76af 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -3591,6 +3591,8 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
 	uint8_t *data = pnt + 3;
 	uint8_t *end = data + hdr->length;
 	char str[BGP_MAX_HOSTNAME + 1] = {};
+	char *new_hostname = NULL;
+	char *new_domainname = NULL;
 	uint8_t len;

 	if (action == CAPABILITY_ACTION_SET) {
@@ -3625,15 +3627,13 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
 		}
 		data += len;

-		XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
-		XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
-
-		peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
+		new_hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);

 		if (data + 1 > end) {
 			flog_err(EC_BGP_CAPABILITY_INVALID_LENGTH,
 				 "%pBP: Received invalid FQDN capability (domain name length)",
 				 peer);
+			XFREE(MTYPE_BGP_PEER_HOST, new_hostname);
 			return;
 		}

@@ -3643,6 +3643,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
 			flog_err(EC_BGP_CAPABILITY_INVALID_LENGTH,
 				 "%pBP: Received invalid FQDN capability length (domain name) %d",
 				 peer, len);
+			XFREE(MTYPE_BGP_PEER_HOST, new_hostname);
 			return;
 		}
 		data++;
@@ -3656,11 +3657,13 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
 		}
 		/* data += len;  In case new code is ever added */

-		if (len) {
-			XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
+		if (len)
+			new_domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);

-			peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
-		}
+		XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
+		XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
+		peer->hostname = new_hostname;
+		peer->domainname = new_domainname;

 		SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
 	} else {