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