Commit dbe6718f0e for frr
commit dbe6718f0ee4dd2f71aa4b99fe32883737c812b8
Author: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Tue Sep 29 11:25:41 2026 +0300
bgpd: Give a hint for Coverity about BGP_DEST_AUTOUNLOCK
Each bgp_node_match() call takes its own lock. When dest1 == dest2, the node
has picked up two extra locks, one per call, on top of whatever the table
already holds.
Coverity treats bgp_dest_unlock_node() as a function that may free,
because of its rn->lock == 1 branch. It doesn't track the counter, so once
it sees two pointers to the same node, it assumes the first unlock freed
it and reports the second as a use-after-free.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 87f0096a48..ea8a7a6392 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -627,6 +627,7 @@ bool bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
ret = (dest1 == dest2);
+ /* coverity[double_free] - aliased dest, locked by each bgp_node_match() */
return ret;
}
@@ -655,6 +656,7 @@ bool bgp_multiaccess_check_v6(struct in6_addr nexthop, struct peer *peer)
ret = (dest1 == dest2);
+ /* coverity[double_free] - aliased dest, locked by each bgp_node_match() */
return ret;
}
@@ -689,6 +691,7 @@ bool bgp_subgrp_multiaccess_check_v6(struct in6_addr nexthop,
dest2 = bgp_node_match(bgp->connected_table[AFI_IP6], &p);
if (dest1 == dest2) {
bgp_dest_unlock_node(dest2);
+ /* coverity[double_free] - aliased dest, locked by each bgp_node_match() */
return true;
}
@@ -731,6 +734,7 @@ bool bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
dest2 = bgp_node_match(bgp->connected_table[AFI_IP], &p);
if (dest1 == dest2) {
bgp_dest_unlock_node(dest2);
+ /* coverity[double_free] - aliased dest, locked by each bgp_node_match() */
return true;
}