tcp/dccp: fix potential NULL deref in __inet_inherit_port()
authorEric Dumazet <edumazet@google.com>
Wed, 14 Oct 2015 12:58:38 +0000 (05:58 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 15 Oct 2015 02:06:31 +0000 (19:06 -0700)
As we no longer hold listener lock in fast path, it is possible that a
child is created right after listener freed its bound port, if a close()
is done while incoming packets are processed.

__inet_inherit_port() must detect this and return an error,
so that caller can free the child earlier.

Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Fixes: 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/inet_hashtables.c

index 08643a3616af70fd3f3ba4ce0d41e258d9f259d9..958728a22001bb514cf47b5a421690062131bcba 100644 (file)
@@ -137,6 +137,10 @@ int __inet_inherit_port(const struct sock *sk, struct sock *child)
 
        spin_lock(&head->lock);
        tb = inet_csk(sk)->icsk_bind_hash;
+       if (unlikely(!tb)) {
+               spin_unlock(&head->lock);
+               return -ENOENT;
+       }
        if (tb->port != port) {
                /* NOTE: using tproxy and redirecting skbs to a proxy
                 * on a different listener port breaks the assumption