Git at Google

commite7f415eadf62add0340ba59b4f6fcaa8c126da7f[log][tgz]
authorJP Abgrall <jpa@google.com>Wed Feb 20 16:38:34 2013 -0800
committerArve Hjønnevåg <arve@android.com>Fri Feb 22 15:27:53 2013 -0800
tree30cfa6e4bd6084fa2430362a93ae61b6cad8b1cc
parent2b9b0b6a95cb7adbdd4fa03bff2c7dec86852aa0[diff]
netfilter: xt_qtaguid: fix bad tcp_time_wait sock handling

Since (41063e9 ipv4: Early TCP socket demux), skb's can have an sk which
is not a struct sock but the smaller struct inet_timewait_sock without an
sk->sk_socket. Now we bypass sk_state == TCP_TIME_WAIT

Signed-off-by: JP Abgrall <jpa@google.com>
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 992a6e0..1b60fdd 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1693,14 +1693,13 @@
 		return NULL;
 	}
 
-	/*
-	 * Seems to be issues on the file ptr for TCP_TIME_WAIT SKs.
-	 * http://kerneltrap.org/mailarchive/linux-netdev/2010/10/21/6287959
-	 * Not fixed in 3.0-r3 :(
-	 */
 	if (sk) {
 		MT_DEBUG("qtaguid: %p->sk_proto=%u "
 			 "->sk_state=%d\n", sk, sk->sk_protocol, sk->sk_state);
+		/*
+		 * When in TCP_TIME_WAIT the sk is not a "struct sock" but
+		 * "struct inet_timewait_sock" which is missing fields.
+		 */
 		if (sk->sk_state  == TCP_TIME_WAIT) {
 			xt_socket_put_sk(sk);
 			sk = NULL;
@@ -1784,6 +1783,13 @@
 	}
 
 	sk = skb->sk;
+	/*
+	 * When in TCP_TIME_WAIT the sk is not a "struct sock" but
+	 * "struct inet_timewait_sock" which is missing fields.
+	 * So we ignore it.
+	 */
+	if (sk && sk->sk_state == TCP_TIME_WAIT)
+		sk = NULL;
 	if (sk == NULL) {
 		/*
 		 * A missing sk->sk_socket happens when packets are in-flight