Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Aug 2005 23:09:51 +0200
From:      Andre Oppermann <andre@freebsd.org>
To:        Max Laier <max@love2party.net>
Cc:        freebsd-net@freebsd.org, ming fu <fming@borderware.com>
Subject:   Re: FreeBSD 5 ip_gre and netisr_enable=1
Message-ID:  <430E339F.3BAEDB8D@freebsd.org>
References:  <430E25A3.8080503@borderware.com> <200508252301.09736.max@love2party.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Max Laier wrote:
> 
> On Thursday 25 August 2005 22:10, ming fu wrote:
> > Hi,
> >
> > This problem exit in some old gre.c (not a part of official freebsd) to
> > handle wccp packets. A carefully crafted packet can cause it to deplete
> > kernel stack and casuing a panic. It can crash a 4.2 kernel with about
> > 200-300 repeated ip+gre header.
> >
> > I believe the problem appears on FreeBSD 5 with ip_gre() and
> > net.isr.enable = 1. It probably easier to crash a 5.x because more calls
> > are involved in FreeBSD 5 than 4.x, thus more stack can be consumed with
> > the same repetition of headers.
> >
> > when a GRE packet gets into the ip_gre2(), its gre header is stripped
> > and sent to netisr_dispatch() for ip_input() processing again. In case,
> > the net.isr.enable is 1, the packet will be delivered to ip_input
> > directly instead of put in the queue.
> >
> > If someone create a packet consists of repeated ip and gre header,
> >
> >     ip hdr : gre hdr : ip hdr : gre hdr : ......     repeat a few
> > hundred times.
> >
> > it can cause a loop around
> > ip_gre->ip_gre2->netisr_dispatch->ip_input->ip_gre ..., not too
> > difficult to deplete the kernel stack.
> >
> > It only takes 24 bytes to force the kernel to go one round through these
> > calls.
> >
> > Any suggestion of how to fix this?
> >
> > send the gre stripped packet to netisr_queue() is an easy, albeit slow
> > solution.
> >
> > I fix the older gre.c file by making sure the inner packet is not a GRE
> > before deliver to ip_input. However, it was ugly to parse the inner
> > header of in ip_gre2().
> 
> You could use an mbuf_tag to keep track of recursion in the same way it is
> done in gif.  There is certainly some overhead involved as well, however.

Or set "m->m_pkthdr.rcvif = self" in gre_output() and in gre_input() check
for (m->m_pkthdr.rcvif != self).

-- 
Andre



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?430E339F.3BAEDB8D>