netfilter: xt_qtaguid: fix bad tcp_time_wait sock handling
JP Abgrall [Thu, 21 Feb 2013 00:38:34 +0000 (16:38 -0800)]
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>

net/netfilter/xt_qtaguid.c

index 4ec6d23..5e07c33 100644 (file)
@@ -1694,14 +1694,13 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
                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;
@@ -1785,6 +1784,13 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
        }
 
        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