net: check the length of the socket address passed to connect(2)
[safe/jmp/linux-2.6] / net / ipv6 / tcp_ipv6.c
index 1c832bf..9b6dbba 100644 (file)
@@ -520,6 +520,13 @@ done:
        return err;
 }
 
+static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
+                            struct request_values *rvp)
+{
+       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+       return tcp_v6_send_synack(sk, req, rvp);
+}
+
 static inline void syn_flood_warning(struct sk_buff *skb)
 {
 #ifdef CONFIG_SYN_COOKIES
@@ -890,10 +897,11 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
 struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
        .family         =       AF_INET6,
        .obj_size       =       sizeof(struct tcp6_request_sock),
-       .rtx_syn_ack    =       tcp_v6_send_synack,
+       .rtx_syn_ack    =       tcp_v6_rtx_synack,
        .send_ack       =       tcp_v6_reqsk_send_ack,
        .destructor     =       tcp_v6_reqsk_destructor,
-       .send_reset     =       tcp_v6_send_reset
+       .send_reset     =       tcp_v6_send_reset,
+       .syn_ack_timeout =      tcp_syn_ack_timeout,
 };
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -1732,8 +1740,11 @@ process:
                        if (!tcp_prequeue(sk, skb))
                                ret = tcp_v6_do_rcv(sk, skb);
                }
-       } else
-               sk_add_backlog(sk, skb);
+       } else if (unlikely(sk_add_backlog(sk, skb))) {
+               bh_unlock_sock(sk);
+               NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP);
+               goto discard_and_relse;
+       }
        bh_unlock_sock(sk);
 
        sock_put(sk);
@@ -2105,7 +2116,7 @@ static struct tcp_seq_afinfo tcp6_seq_afinfo = {
        },
 };
 
-int tcp6_proc_init(struct net *net)
+int __net_init tcp6_proc_init(struct net *net)
 {
        return tcp_proc_register(net, &tcp6_seq_afinfo);
 }
@@ -2174,18 +2185,18 @@ static struct inet_protosw tcpv6_protosw = {
                                INET_PROTOSW_ICSK,
 };
 
-static int tcpv6_net_init(struct net *net)
+static int __net_init tcpv6_net_init(struct net *net)
 {
        return inet_ctl_sock_create(&net->ipv6.tcp_sk, PF_INET6,
                                    SOCK_RAW, IPPROTO_TCP, net);
 }
 
-static void tcpv6_net_exit(struct net *net)
+static void __net_exit tcpv6_net_exit(struct net *net)
 {
        inet_ctl_sock_destroy(net->ipv6.tcp_sk);
 }
 
-static void tcpv6_net_exit_batch(struct list_head *net_exit_list)
+static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
 {
        inet_twsk_purge(&tcp_hashinfo, &tcp_death_row, AF_INET6);
 }