diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-01-25 23:54:22 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2020-01-25 23:54:22 +0000 |
commit | b4ce8095e2c0bee6d106fa1268ac6f25672e34c0 (patch) | |
tree | 28619cee2c5ae2dddac0197ab0e283d4b17d8411 /usr.sbin/bgpd/rde_rib.c | |
parent | 724282114881f26a38a2330699f5dd9ddf19346f (diff) |
In nexthop_update() only add a nexthop to the nexthop_runners queue if
there is actual work to do (nh->next_prefix != NULL). If next_prefix
is NULL there is a possibility that nexthop_unref() is called before
the nexthop is removed from the nexthop_runners queue resulting in a
use-after-free access in nexthop_runner().
For consistency add a debug message in nexthop_unlink() if the nexthop
is removed from the nexthop_runners queue because the last prefix is gone.
OK procter@
Diffstat (limited to 'usr.sbin/bgpd/rde_rib.c')
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index 3ec427683e1..a5be60ffda1 100644 --- a/usr.sbin/bgpd/rde_rib.c +++ b/usr.sbin/bgpd/rde_rib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_rib.c,v 1.214 2020/01/10 14:52:57 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.215 2020/01/25 23:54:21 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -1800,8 +1800,11 @@ nexthop_update(struct kroute_nexthop *msg) nh->nexthop_netlen = msg->netlen; nh->next_prefix = LIST_FIRST(&nh->prefix_h); - TAILQ_INSERT_HEAD(&nexthop_runners, nh, runner_l); - log_debug("nexthop %s update starting", log_addr(&nh->exit_nexthop)); + if (nh->next_prefix != NULL) { + TAILQ_INSERT_HEAD(&nexthop_runners, nh, runner_l); + log_debug("nexthop %s update starting", + log_addr(&nh->exit_nexthop)); + } } void @@ -1860,8 +1863,11 @@ nexthop_unlink(struct prefix *p) if (p == p->nexthop->next_prefix) { p->nexthop->next_prefix = LIST_NEXT(p, entry.list.nexthop); /* remove nexthop from list if no prefixes left to update */ - if (p->nexthop->next_prefix == NULL) + if (p->nexthop->next_prefix == NULL) { TAILQ_REMOVE(&nexthop_runners, p->nexthop, runner_l); + log_debug("nexthop %s update finished", + log_addr(&p->nexthop->exit_nexthop)); + } } p->flags &= ~PREFIX_NEXTHOP_LINKED; |