Module Name:    src
Committed By:   rmind
Date:           Sat Oct  6 23:50:17 UTC 2012

Modified Files:
        src/sys/net/npf: npf_state_tcp.c

Log Message:
npf_tcp_inwindow: inspect the sequence numbers even if the packet contains no
data, fixing up only the RST to the initial SYN.  This makes off-path attacks
more difficult.  For the reference, see "Reflection Scan: an Off-Path Attack
on TCP" by Jan Wrobel.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/net/npf/npf_state_tcp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/npf/npf_state_tcp.c
diff -u src/sys/net/npf/npf_state_tcp.c:1.10 src/sys/net/npf/npf_state_tcp.c:1.11
--- src/sys/net/npf/npf_state_tcp.c:1.10	Sat Jul 21 17:11:02 2012
+++ src/sys/net/npf/npf_state_tcp.c	Sat Oct  6 23:50:17 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state_tcp.c,v 1.10 2012/07/21 17:11:02 rmind Exp $	*/
+/*	$NetBSD: npf_state_tcp.c,v 1.11 2012/10/06 23:50:17 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.10 2012/07/21 17:11:02 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.11 2012/10/06 23:50:17 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -94,6 +94,8 @@ static u_int npf_tcp_timeouts[] __read_m
 	[NPF_TCPS_TIME_WAIT]	= 60 * 2 * 2,
 };
 
+static bool npf_strict_order_rst __read_mostly = false;
+
 #define	NPF_TCP_MAXACKWIN	66000
 
 /*
@@ -391,17 +393,20 @@ npf_tcp_inwindow(const npf_cache_t *npc,
 		/* Workaround for some TCP stacks. */
 		ack = tstate->nst_end;
 	}
-	if (seq == end) {
-		/* If packet contains no data - assume it is valid. */
-		end = fstate->nst_end;
-		seq = end;
-	}
-#if 0
-	/* Strict in-order sequence for RST packets. */
-	if ((tcpfl & TH_RST) != 0 && (fstate->nst_end - seq) > 1) {
-		return false;
+
+	if (__predict_false(tcpfl & TH_RST)) {
+		/* RST to the initial SYN may have zero SEQ - fix it up. */
+		if (seq == 0 && nst->nst_state == NPF_TCPS_SYN_SENT) {
+			end = fstate->nst_end;
+			seq = end;
+		}
+
+		/* Strict in-order sequence for RST packets. */
+		if (npf_strict_order_rst && (fstate->nst_end - seq) > 1) {
+			return false;
+		}
 	}
-#endif
+
 	/*
 	 * Determine whether the data is within previously noted window,
 	 * that is, upper boundary for valid data (I).

Reply via email to