aboutsummaryrefslogtreecommitdiff
path: root/sys/net/route.c
diff options
context:
space:
mode:
authorJohn Polstra <jdp@FreeBSD.org>1999-12-09 17:09:37 +0000
committerJohn Polstra <jdp@FreeBSD.org>1999-12-09 17:09:37 +0000
commit68f956b85ee7b017f2a918323d13846df3627e27 (patch)
tree72fafb62e2f5970748588cadc6abb27c507a5ec1 /sys/net/route.c
parent7466caf46a72524a49956587124fb94125cdf661 (diff)
downloadsrc-68f956b85ee7b017f2a918323d13846df3627e27.tar.gz
src-68f956b85ee7b017f2a918323d13846df3627e27.zip
Fix a route table leak in rtalloc() and rtalloc_ign(). It is
possible for ro->ro_rt to be non-NULL even though the RTF_UP flag is cleared. (Example: a routing daemon or the "route" command deletes a cloned route in active use by a TCP connection.) In that case, the code was clobbering a reference to the routing table entry without decrementing the entry's reference count. The splnet() call probably isn't needed, but I haven't been able to prove that yet. It isn't significant from a performance standpoint since it is executed very rarely. Reviewed by: wollman and others in the freebsd-current mailing list
Notes
Notes: svn path=/head/; revision=54369
Diffstat (limited to 'sys/net/route.c')
-rw-r--r--sys/net/route.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 04608f58e916..45e0e39ae7cc 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -88,9 +88,7 @@ void
rtalloc(ro)
register struct route *ro;
{
- if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
- return; /* XXX */
- ro->ro_rt = rtalloc1(&ro->ro_dst, 1, 0UL);
+ rtalloc_ign(ro, 0UL);
}
void
@@ -98,8 +96,17 @@ rtalloc_ign(ro, ignore)
register struct route *ro;
u_long ignore;
{
- if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
- return; /* XXX */
+ struct rtentry *rt;
+ int s;
+
+ if ((rt = ro->ro_rt) != NULL) {
+ if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
+ return;
+ /* XXX - We are probably always at splnet here already. */
+ s = splnet();
+ RTFREE(rt);
+ splx(s);
+ }
ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore);
}