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>