summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgerhard <gerhard@openbsd.org>2014-11-03 11:43:47 +0000
committergerhard <gerhard@openbsd.org>2014-11-03 11:43:47 +0000
commit94cf9181d2cd9d61506d80375ba04b046707bde4 (patch)
treedcb3ce668ecae06b8a8ec664ede068071777ba15
parentDo no change the gateway of local routes for p2p interfaces. (diff)
downloadwireguard-openbsd-94cf9181d2cd9d61506d80375ba04b046707bde4.tar.xz
wireguard-openbsd-94cf9181d2cd9d61506d80375ba04b046707bde4.zip
Fix kernel stack overflow by preventing carp_send_ad_all() from re-entrant
calls. Also, when adjusting demote counts, don't call carp_send_ad_all() for every ifgroup with a demote count of 1 but rather call it only once after adjusting the demote counts of all ifgroups. ok bluhm@ mpf@
-rw-r--r--sys/netinet/ip_carp.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 20678436cfe..d3ef05cae66 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.236 2014/10/07 08:47:28 mpi Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.237 2014/11/03 11:43:47 gerhard Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -170,6 +170,8 @@ struct carp_softc {
int carp_opts[CARPCTL_MAXID] = { 0, 1, 0, LOG_CRIT }; /* XXX for now */
struct carpstats carpstats;
+int carp_send_all_recur = 0;
+
struct carp_if {
TAILQ_HEAD(, carp_softc) vhif_vrs;
int vhif_nvrs;
@@ -925,6 +927,9 @@ carp_send_ad_all(void)
struct carp_if *cif;
struct carp_softc *vh;
+ if (carp_send_all_recur > 0)
+ return;
+ ++carp_send_all_recur;
TAILQ_FOREACH(ifp, &ifnet, if_list) {
if (ifp->if_carp == NULL || ifp->if_type == IFT_CARP)
continue;
@@ -937,6 +942,7 @@ carp_send_ad_all(void)
}
}
}
+ --carp_send_all_recur;
}
void
@@ -2424,7 +2430,7 @@ void
carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
{
struct ifg_list *ifgl;
- int *dm;
+ int *dm, need_ad;
struct carp_softc *nil = NULL;
if (ifp->if_type == IFT_CARP) {
@@ -2435,6 +2441,7 @@ carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
*dm = 0;
}
+ need_ad = 0;
TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
if (!strcmp(ifgl->ifgl_group->ifg_group, IFG_ALL))
continue;
@@ -2446,12 +2453,14 @@ carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason)
*dm = 0;
if (adj > 0 && *dm == 1)
- carp_send_ad_all();
+ need_ad = 1;
CARP_LOG(LOG_ERR, nil,
("%s demoted group %s by %d to %d (%s)",
ifp->if_xname, ifgl->ifgl_group->ifg_group,
adj, *dm, reason));
}
+ if (need_ad)
+ carp_send_ad_all();
}
int