| From foo@baz Mon Jan 18 21:18:36 PST 2016 |
| From: Eric Dumazet <edumazet@google.com> |
| Date: Wed, 9 Dec 2015 07:25:06 -0800 |
| Subject: ipv6: sctp: clone options to avoid use after free |
| Status: RO |
| Content-Length: 1365 |
| Lines: 47 |
| |
| From: Eric Dumazet <edumazet@google.com> |
| |
| [ 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 | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/net/sctp/ipv6.c |
| +++ b/net/sctp/ipv6.c |
| @@ -639,6 +639,7 @@ static struct sock *sctp_v6_create_accep |
| 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_accep |
| |
| 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(). |
| */ |