Subject: kern/21483: misconfigured gre may lead to unbound recursion
To: None <gnats-bugs@gnats.netbsd.org>
From: Martin Husemann <martin@aprisoft.de>
List: netbsd-bugs
Date: 05/06/2003 18:13:34
>Number: 21483
>Category: kern
>Synopsis: misconfigured gre may lead to unbound recursion
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue May 06 16:14:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Martin Husemann
>Release: NetBSD 1.6R
>Organization:
>Environment:
System: NetBSD beasty.aprisoft.de 1.6R NetBSD 1.6R (BEASTY) #0: Tue Apr 29 17:15:27 CEST 2003 martin@beasty.aprisoft.de:/usr/src/sys/arch/i386/compile/BEASTY i386
Architecture: i386
Machine: i386
>Description:
sys/net/if_gre.c tries to avoid sending packets through the tunnel, when
gre_compute_route failed (i.e. the far end of the tunnel is not reachable
outside the tunnel itself). It sets IFF_RUNNING if the route is available
and clears it otherwise.
I think in gre_output the test for IFF_UP + IFF_RUNNING is slightly wrong,
so packets pass if only IFF_UP is set. This leads to recursive routing
and kernel stack overflows.
>How-To-Repeat:
Code review.
>Fix:
Besides the above fix, I'd suggest adding some diagnostic output when failing
to find a route. This is unrelated, but included in the following patch
anyway.
Index: if_gre.c
===================================================================
RCS file: /cvsroot/src/sys/net/if_gre.c,v
retrieving revision 1.44
diff -u -r1.44 if_gre.c
--- if_gre.c 2003/02/23 04:28:10 1.44
+++ if_gre.c 2003/05/06 16:07:57
@@ -191,7 +191,7 @@
u_short etype = 0;
struct mobile_h mob_h;
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 0 ||
+ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING) ||
sc->g_src.s_addr == INADDR_ANY || sc->g_dst.s_addr == INADDR_ANY) {
m_freem(m);
error = ENETDOWN;
@@ -441,8 +441,11 @@
RTFREE(sc->route.ro_rt);
if (gre_compute_route(sc) == 0)
ifp->if_flags |= IFF_RUNNING;
- else
+ else {
ifp->if_flags &= ~IFF_RUNNING;
+ printf("%s: configuration problem, no tunnel "
+ "route found\n", ifp->if_xname);
+ }
}
break;
case GREGADDRS:
>Release-Note:
>Audit-Trail:
>Unformatted: