From owner-freebsd-net@FreeBSD.ORG Thu Aug 25 20:10:13 2005 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 950D616A41F for ; Thu, 25 Aug 2005 20:10:13 +0000 (GMT) (envelope-from fming@borderware.com) Received: from mail.borderware.com (mail.borderware.com [207.236.65.231]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2ADD443D48 for ; Thu, 25 Aug 2005 20:10:12 +0000 (GMT) (envelope-from fming@borderware.com) Message-ID: <430E25A3.8080503@borderware.com> Date: Thu, 25 Aug 2005 16:10:11 -0400 From: ming fu User-Agent: Debian Thunderbird 1.0.2 (X11/20050602) X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: FreeBSD 5 ip_gre and netisr_enable=1 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Aug 2005 20:10:13 -0000 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