summaryrefslogtreecommitdiff
path: root/sys/net/rtable.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2019-06-21 17:11:44 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2019-06-21 17:11:44 +0000
commitfb482f64f911b7fca87d82ac917a331783e5915c (patch)
tree5de16192a2d5c2016a8f06548095348d71e6ebdf /sys/net/rtable.c
parentd54cd84095c832ef5111a5e80e44ec90ec860873 (diff)
Prevent recursions by not deleting entries inside rtable_walk(9).
rtable_walk(9) now passes a routing entry back to the caller when a non zero value is returned and if it asked for it. This allows us to call rtdeletemsg()/rtrequest_delete() from the caller without creating a recursion because of rtflushclone(). Multicast code hasn't been adapted and is still possibly creating recursions. However multicast route entries aren't cloned so if a recursion exists it isn't because of rtflushclone(). Fix stack exhaustion triggered by the use of "-msave-args". Issue reported by Dániel Lévai on bugs@ confirmed by and ok bluhm@.
Diffstat (limited to 'sys/net/rtable.c')
-rw-r--r--sys/net/rtable.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/net/rtable.c b/sys/net/rtable.c
index 092d53b265f..ec57747f447 100644
--- a/sys/net/rtable.c
+++ b/sys/net/rtable.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtable.c,v 1.68 2019/03/05 19:07:56 anton Exp $ */
+/* $OpenBSD: rtable.c,v 1.69 2019/06/21 17:11:42 mpi Exp $ */
/*
* Copyright (c) 2014-2016 Martin Pieuchot
@@ -664,6 +664,7 @@ leave:
struct rtable_walk_cookie {
int (*rwc_func)(struct rtentry *, void *, unsigned int);
void *rwc_arg;
+ struct rtentry **rwc_prt;
unsigned int rwc_rid;
};
@@ -679,16 +680,21 @@ rtable_walk_helper(struct art_node *an, void *xrwc)
int error = 0;
SRPL_FOREACH(rt, &sr, &an->an_rtlist, rt_next) {
- if ((error = (*rwc->rwc_func)(rt, rwc->rwc_arg, rwc->rwc_rid)))
+ error = (*rwc->rwc_func)(rt, rwc->rwc_arg, rwc->rwc_rid);
+ if (error != 0)
break;
}
+ if (rwc->rwc_prt != NULL && rt != NULL) {
+ rtref(rt);
+ *rwc->rwc_prt = rt;
+ }
SRPL_LEAVE(&sr);
return (error);
}
int
-rtable_walk(unsigned int rtableid, sa_family_t af,
+rtable_walk(unsigned int rtableid, sa_family_t af, struct rtentry **prt,
int (*func)(struct rtentry *, void *, unsigned int), void *arg)
{
struct art_root *ar;
@@ -701,10 +707,10 @@ rtable_walk(unsigned int rtableid, sa_family_t af,
rwc.rwc_func = func;
rwc.rwc_arg = arg;
+ rwc.rwc_prt = prt;
rwc.rwc_rid = rtableid;
- while ((error = art_walk(ar, rtable_walk_helper, &rwc)) == EAGAIN)
- continue;
+ error = art_walk(ar, rtable_walk_helper, &rwc);
return (error);
}