diff options
author | jca <jca@openbsd.org> | 2017-01-17 16:30:54 +0000 |
---|---|---|
committer | jca <jca@openbsd.org> | 2017-01-17 16:30:54 +0000 |
commit | b38873a29ec2819ac536d9d8f60f452e50547180 (patch) | |
tree | 4cb362ef10e23a68f20222281b8278f82970199f /usr.sbin/ripd | |
parent | Completely delete the buf field of struct html and all the buf*() (diff) | |
download | wireguard-openbsd-b38873a29ec2819ac536d9d8f60f452e50547180.tar.xz wireguard-openbsd-b38873a29ec2819ac536d9d8f60f452e50547180.zip |
Keep track of dead peers instead of freeing them right away.
This mimics what ospfd does, and avoids a (mostly harmless)
use-after-free. Delay suggested by claudio@, ok florian@
Diffstat (limited to 'usr.sbin/ripd')
-rw-r--r-- | usr.sbin/ripd/interface.c | 4 | ||||
-rw-r--r-- | usr.sbin/ripd/neighbor.c | 33 | ||||
-rw-r--r-- | usr.sbin/ripd/ripe.h | 6 |
3 files changed, 28 insertions, 15 deletions
diff --git a/usr.sbin/ripd/interface.c b/usr.sbin/ripd/interface.c index 36c60fe2794..79b2424243d 100644 --- a/usr.sbin/ripd/interface.c +++ b/usr.sbin/ripd/interface.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.c,v 1.13 2015/09/27 17:32:36 stsp Exp $ */ +/* $OpenBSD: interface.c,v 1.14 2017/01/17 16:30:54 jca Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -467,7 +467,7 @@ if_del(struct iface *iface) /* clear lists etc */ while ((nbr = LIST_FIRST(&iface->nbr_list)) != NULL) - nbr_act_del(nbr); + nbr_del(nbr); /* XXX rq_list, rp_list */ diff --git a/usr.sbin/ripd/neighbor.c b/usr.sbin/ripd/neighbor.c index 29f5b893519..7d8248513a2 100644 --- a/usr.sbin/ripd/neighbor.c +++ b/usr.sbin/ripd/neighbor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: neighbor.c,v 1.10 2016/07/18 21:20:31 benno Exp $ */ +/* $OpenBSD: neighbor.c,v 1.11 2017/01/17 16:30:54 jca Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -203,6 +203,21 @@ nbr_new(u_int32_t nbr_id, struct iface *iface) } void +nbr_del(struct nbr *nbr) +{ + log_debug("nbr_del: neighbor ID %s, peerid %u", inet_ntoa(nbr->id), + nbr->peerid); + + /* stop timer */ + nbr_stop_timer(nbr); + + LIST_REMOVE(nbr, entry); + LIST_REMOVE(nbr, hash); + + free(nbr); +} + +void nbr_act_del(struct nbr *nbr) { /* If there is no authentication or it is just a route request @@ -211,20 +226,15 @@ nbr_act_del(struct nbr *nbr) nbr->state != NBR_STA_REQ_RCVD) nbr_failed_new(nbr); - log_debug("nbr_del: neighbor ID %s, peerid %u", inet_ntoa(nbr->id), + log_debug("nbr_act_del: neighbor ID %s, peerid %u", inet_ntoa(nbr->id), nbr->peerid); - /* stop timer */ - nbr_stop_timer(nbr); + /* schedule kill timer */ + nbr_set_timer(nbr); /* clear lists */ clear_list(&nbr->rq_list); clear_list(&nbr->rp_list); - - LIST_REMOVE(nbr, entry); - LIST_REMOVE(nbr, hash); - - free(nbr); } struct nbr * @@ -316,7 +326,10 @@ nbr_timeout_timer(int fd, short event, void *arg) { struct nbr *nbr = arg; - nbr_fsm(nbr, NBR_EVT_TIMEOUT); + if (nbr->state == NBR_STA_DOWN) + nbr_del(nbr); + else + nbr_fsm(nbr, NBR_EVT_TIMEOUT); } /* ARGSUSED */ diff --git a/usr.sbin/ripd/ripe.h b/usr.sbin/ripd/ripe.h index 8b7020fb5e6..7dc48139c1d 100644 --- a/usr.sbin/ripd/ripe.h +++ b/usr.sbin/ripd/ripe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ripe.h,v 1.11 2014/10/25 03:23:49 lteo Exp $ */ +/* $OpenBSD: ripe.h,v 1.12 2017/01/17 16:30:54 jca Exp $ */ /* * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> @@ -128,7 +128,7 @@ void md_list_clr(struct auth_md_head *); /* neighbor.c */ void nbr_init(u_int32_t); struct nbr *nbr_new(u_int32_t, struct iface *); -void nbr_act_del(struct nbr *); +void nbr_del(struct nbr *); struct nbr *nbr_find_ip(struct iface *, u_int32_t); struct nbr *nbr_find_peerid(u_int32_t); @@ -137,7 +137,7 @@ void nbr_failed_delete(struct nbr_failed *); int nbr_fsm(struct nbr *, enum nbr_event); void nbr_timeout_timer(int, short, void *); -void nbr_act_delete(struct nbr *); +void nbr_act_del(struct nbr *); const char *nbr_event_name(int); const char *nbr_action_name(int); |