aboutsummaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2021-06-01 01:59:20 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2021-06-01 02:20:26 +0200
commit91d04583891f7a6f4aee612cf3f143cc84a73991 (patch)
tree5b1ba385485532bf8424a3a8ab76f411e6cd0601 /proto
parentebd5751cdeb4c753c6c9df31b82dcd6afee2cd39 (diff)
downloadbird-91d04583891f7a6f4aee612cf3f143cc84a73991.tar.gz
BGP: Ensure that freed neighbor entry is not accessed
Routes from downed protocols stay in rtable (until next rtable prune cycle ends) and may be even exported to another protocol. In BGP case, source BGP protocol is examined, although dynamic parts (including neighbor entries) are already freed. That may lead to crash under some race conditions. Ensure that freed neighbor entry is not accessed to avoid this issue.
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/bgp.c4
-rw-r--r--proto/bgp/packets.c3
2 files changed, 6 insertions, 1 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 1adb930d..e4d754b1 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -337,6 +337,8 @@ err2:
err1:
p->p.disabled = 1;
bgp_store_error(p, NULL, BE_MISC, err_val);
+
+ p->neigh = NULL;
proto_notify_state(&p->p, PS_DOWN);
return;
@@ -473,6 +475,8 @@ bgp_down(struct bgp_proto *p)
bgp_close(p);
}
+ p->neigh = NULL;
+
BGP_TRACE(D_EVENTS, "Down");
proto_notify_state(&p->p, PS_DOWN);
}
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index b16ee242..99b5d5b4 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -1051,7 +1051,8 @@ bgp_use_next_hop(struct bgp_export_state *s, eattr *a)
return 1;
/* Keep it when forwarded between single-hop BGPs on the same iface */
- struct iface *ifa = (s->src && s->src->neigh) ? s->src->neigh->iface : NULL;
+ struct iface *ifa = (s->src && s->src->neigh && (s->src->p.proto_state != PS_DOWN)) ?
+ s->src->neigh->iface : NULL;
return p->neigh && (p->neigh->iface == ifa);
}