]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
ipv6: sctp: clone options to avoid use after free
authorEric Dumazet <edumazet@google.com>
Wed, 9 Dec 2015 15:25:06 +0000 (07:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Jan 2016 03:47:54 +0000 (19:47 -0800)
[ Upstream commit 9470e24f35ab81574da54e69df90c1eb4a96b43f ]

SCTP is lacking proper np->opt cloning at accept() time.

TCP and DCCP use ipv6_dup_options() helper, do the same
in SCTP.

We might later factorize this code in a common helper to avoid
future mistakes.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/sctp/ipv6.c

index 422d8bdacc0d930244eb4f4fb4e34cce1c538d9c..bee032a7003f0f367e1bb27f5dfc620658b76a58 100644 (file)
@@ -639,6 +639,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        struct sock *newsk;
        struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
        struct sctp6_sock *newsctp6sk;
+       struct ipv6_txoptions *opt;
 
        newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot);
        if (!newsk)
@@ -658,6 +659,13 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
 
        memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
+       rcu_read_lock();
+       opt = rcu_dereference(np->opt);
+       if (opt)
+               opt = ipv6_dup_options(newsk, opt);
+       RCU_INIT_POINTER(newnp->opt, opt);
+       rcu_read_unlock();
+
        /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
         * and getpeername().
         */