Skip to content

Commit ec8a02a

Browse files
committed
bgpd: bgp_clear_adj_in|remove dest may be freed
dest will not be freed due to lock but coverity does not know that. Give it a hint. This change includes modifying bgp_dest_unlock_node to return the dest pointer so that we can determine if we should continue working on dest or not with an assert. Since this is lock based we should be ok. Signed-off-by: Donald Sharp <[email protected]>
1 parent bee4e27 commit ec8a02a

File tree

5 files changed

+18
-9
lines changed

5 files changed

+18
-9
lines changed

bgpd/bgp_advertise.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,11 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr,
188188
bgp_dest_lock_node(dest);
189189
}
190190

191-
void bgp_adj_in_remove(struct bgp_dest *dest, struct bgp_adj_in *bai)
191+
void bgp_adj_in_remove(struct bgp_dest **dest, struct bgp_adj_in *bai)
192192
{
193193
bgp_attr_unintern(&bai->attr);
194-
BGP_ADJ_IN_DEL(dest, bai);
195-
bgp_dest_unlock_node(dest);
194+
BGP_ADJ_IN_DEL(*dest, bai);
195+
*dest = bgp_dest_unlock_node(*dest);
196196
peer_unlock(bai->peer); /* adj_in peer reference */
197197
XFREE(MTYPE_BGP_ADJ_IN, bai);
198198
}
@@ -212,9 +212,11 @@ bool bgp_adj_in_unset(struct bgp_dest *dest, struct peer *peer,
212212
adj_next = adj->next;
213213

214214
if (adj->peer == peer && adj->addpath_rx_id == addpath_id)
215-
bgp_adj_in_remove(dest, adj);
215+
bgp_adj_in_remove(&dest, adj);
216216

217217
adj = adj_next;
218+
219+
assert(dest);
218220
}
219221

220222
return true;

bgpd/bgp_advertise.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ extern void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer,
132132
struct attr *attr, uint32_t addpath_id);
133133
extern bool bgp_adj_in_unset(struct bgp_dest *dest, struct peer *peer,
134134
uint32_t addpath_id);
135-
extern void bgp_adj_in_remove(struct bgp_dest *dest, struct bgp_adj_in *bai);
135+
extern void bgp_adj_in_remove(struct bgp_dest **dest, struct bgp_adj_in *bai);
136136

137137
extern unsigned int bgp_advertise_attr_hash_key(const void *p);
138138
extern bool bgp_advertise_attr_hash_cmp(const void *p1, const void *p2);

bgpd/bgp_route.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -5671,9 +5671,11 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
56715671
ain_next = ain->next;
56725672

56735673
if (ain->peer == peer)
5674-
bgp_adj_in_remove(dest, ain);
5674+
bgp_adj_in_remove(&dest, ain);
56755675

56765676
ain = ain_next;
5677+
5678+
assert(dest);
56775679
}
56785680

56795681
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
@@ -5778,9 +5780,11 @@ void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
57785780
ain_next = ain->next;
57795781

57805782
if (ain->peer == peer)
5781-
bgp_adj_in_remove(dest, ain);
5783+
bgp_adj_in_remove(&dest, ain);
57825784

57835785
ain = ain_next;
5786+
5787+
assert(dest);
57845788
}
57855789
}
57865790
}

bgpd/bgp_table.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const char *bgp_dest_get_prefix_str(struct bgp_dest *dest)
7575
/*
7676
* bgp_dest_unlock_node
7777
*/
78-
inline void bgp_dest_unlock_node(struct bgp_dest *dest)
78+
inline struct bgp_dest *bgp_dest_unlock_node(struct bgp_dest *dest)
7979
{
8080
frrtrace(1, frr_bgp, bgp_dest_unlock, dest);
8181
bgp_delete_listnode(dest);
@@ -89,9 +89,12 @@ inline void bgp_dest_unlock_node(struct bgp_dest *dest)
8989
rt->safi);
9090
}
9191
XFREE(MTYPE_BGP_NODE, dest);
92+
dest = NULL;
9293
rn->info = NULL;
9394
}
9495
route_unlock_node(rn);
96+
97+
return dest;
9598
}
9699

97100
/*

bgpd/bgp_table.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ extern struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t, safi_t);
112112
extern void bgp_table_lock(struct bgp_table *);
113113
extern void bgp_table_unlock(struct bgp_table *);
114114
extern void bgp_table_finish(struct bgp_table **);
115-
extern void bgp_dest_unlock_node(struct bgp_dest *dest);
115+
extern struct bgp_dest *bgp_dest_unlock_node(struct bgp_dest *dest);
116116
extern struct bgp_dest *bgp_dest_lock_node(struct bgp_dest *dest);
117117
extern const char *bgp_dest_get_prefix_str(struct bgp_dest *dest);
118118

0 commit comments

Comments
 (0)