kern/149937: kernel panic in ipfilter IP fragments with TCP paylaod in reverse order

Jens Kassel jens.kassel at servicefactory.com
Tue Aug 24 14:00:03 UTC 2010


>Number:         149937
>Category:       kern
>Synopsis:       kernel panic in ipfilter IP fragments with TCP paylaod in reverse order
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 24 14:00:02 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Jens Kassel
>Release:        FreeBSD 7.2
>Organization:
Servicefactory AB
>Environment:
FreeBSD h167.servicefactory.com 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Fri May  1 08:49:13 UTC 2009     root at walker.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
Kernel panic in ipfilter when trying to NAT IP fragments with TCP payload sent in "wrong" order. The following line in ip_nat.c will crash on NULL pointer.



 if (nat->nat_p == IPPROTO_TCP)
                nat->nat_seqnext[0] = ntohl(tcp->th_seq);


tcp is not set.


This is not fixed in FreeBSD 8.1
>How-To-Repeat:
Set up ipnat:
List of active MAP/Redirect filters:
map bge2 10.10.0.0/24 -> 0.0.0.0/32 proxy port ftp ftp/tcp
map bge2 10.10.0.0/24 -> 0.0.0.0/32 portmap tcp/udp 1025:65500
map bge2 10.10.0.0/24 -> 0.0.0.0/32
map lo3 10.10.0.0/24 -> 127.0.0.3/32 portmap tcp/udp 9000:65500
map lo0 10.10.0.0/24 -> 127.0.0.1/32 portmap udp 9000:65500
map-block lo0 10.10.0.0/24 -> 127.0.0.1/32 ports 10 tcp
rdr lo0 0.0.0.0/0 port 80 -> 127.0.0.1 port 65501 tcp
rdr lo0 0.0.0.0/0 port 443 -> 127.0.0.1 port 65502 tcp
rdr lo3 0.0.0.0/0 port 8080 -> 127.0.0.3 port 65504 tcp
rdr lo1 0.0.0.0/0 port 8080 -> 127.0.0.2 port 65503 tcp
map lo1 10.10.0.0/24 -> 127.0.0.2/32 portmap tcp/udp 9000:65500

List of active sessions:



Send correct fragmented IP packet with proto TCP and offset larger than 0 (not first fragment). Source 10.10.0.x. Destination some externel host.
>Fix:
The following patch will discard these fragments if sent in reverse order (solving the problem).


--- ip_nat.c.org        2010-08-24 13:43:56.000000000 +0200
+++ ip_nat.c    2010-08-24 14:41:33.000000000 +0200
@@ -3770,6 +3770,17 @@
                if ((nflags & IPN_TCPUDP))
                        tcp = fin->fin_dp;
        }
+       else
+        {
+                /* Discard TCP unknown fragments out of order
+                */
+                if ((IPPROTO_TCP == fin->fin_p) &&  !fr_nat_knownfrag(fin))
+                {
+                       nat_stats.ns_badnat++;
+                        return -1;
+                }
+        }
+

        ipa = fin->fin_saddr;

@@ -4065,6 +4076,17 @@
                        dport = tcp->th_dport;
                }
        }
+       else
+        {
+                /* Discard TCP unknown fragments out of order
+                */
+                if ((IPPROTO_TCP == fin->fin_p) &&  !fr_nat_knownfrag(fin))
+                {
+                       nat_stats.ns_badnat++;
+                        return -1;
+                }
+        }
+

        in = fin->fin_dst;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list