tcp/dccp: do not touch listener sk_refcnt under synflood
[linux-block.git] / net / dccp / ipv6.c
index 4663a01d503991c138c56da530544791832fee5f..71bf1deba4c5ede428baee490a2af0802133f47d 100644 (file)
@@ -642,6 +642,7 @@ discard:
 static int dccp_v6_rcv(struct sk_buff *skb)
 {
        const struct dccp_hdr *dh;
+       bool refcounted;
        struct sock *sk;
        int min_cov;
 
@@ -670,7 +671,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
 lookup:
        sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
                                dh->dccph_sport, dh->dccph_dport,
-                               inet6_iif(skb));
+                               inet6_iif(skb), &refcounted);
        if (!sk) {
                dccp_pr_debug("failed to look up flow ID in table and "
                              "get corresponding socket\n");
@@ -699,6 +700,7 @@ lookup:
                        goto lookup;
                }
                sock_hold(sk);
+               refcounted = true;
                nsk = dccp_check_req(sk, skb, req);
                if (!nsk) {
                        reqsk_put(req);
@@ -752,7 +754,8 @@ discard_it:
        return 0;
 
 discard_and_relse:
-       sock_put(sk);
+       if (refcounted)
+               sock_put(sk);
        goto discard_it;
 }