Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Aug 2005 16:10:11 -0400
From:      ming fu <fming@borderware.com>
To:        freebsd-net@freebsd.org
Subject:   FreeBSD 5 ip_gre and netisr_enable=1
Message-ID:  <430E25A3.8080503@borderware.com>

next in thread | raw e-mail | index | archive | help
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().

Regards,
Ming



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