mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Route sources have an explicit owner
This commit prevents use-after-free of routes belonging to protocols which have been already destroyed, delaying also all the protocols' shutdown until all of their routes have been finally propagated through all the pipes down to the appropriate exports. The use-after-free was somehow hypothetic yet theoretically possible in rare conditions, when one BGP protocol authors a lot of routes and the user deletes that protocol by reconfiguring in the same time as next hop update is requested, causing rte_better() to be called on a not-yet-pruned network prefix while the owner protocol has been already freed. In parallel execution environments, this would happen an inter-thread use-after-free, causing possible heisenbugs or other nasty problems.
This commit is contained in:
@@ -294,8 +294,9 @@ krt_rte_better(rte *a, rte *b)
|
||||
static void
|
||||
krt_learn_rte(struct krt_proto *p, rte *e)
|
||||
{
|
||||
e->src = rt_get_source(&p->p, krt_metric(e));
|
||||
struct rte_src *src = e->src = rt_get_source(&p->p, krt_metric(e));
|
||||
rte_update(p->p.main_channel, e->net, e, e->src);
|
||||
rt_unlock_source(src);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -674,7 +675,7 @@ krt_scan_timer_kick(struct krt_proto *p)
|
||||
static int
|
||||
krt_preexport(struct channel *c, rte *e)
|
||||
{
|
||||
if (e->src->proto == c->proto)
|
||||
if (e->src->owner == &c->proto->sources)
|
||||
return -1;
|
||||
|
||||
if (!krt_capable(e))
|
||||
|
||||
Reference in New Issue
Block a user