Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv6: sctp: clone options to avoid use after free

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>

authored by

Eric Dumazet and committed by
David S. Miller
9470e24f d188ba86

+8
+8
net/sctp/ipv6.c
··· 641 641 struct sock *newsk; 642 642 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 643 643 struct sctp6_sock *newsctp6sk; 644 + struct ipv6_txoptions *opt; 644 645 645 646 newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, 0); 646 647 if (!newsk) ··· 660 659 newnp = inet6_sk(newsk); 661 660 662 661 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 662 + 663 + rcu_read_lock(); 664 + opt = rcu_dereference(np->opt); 665 + if (opt) 666 + opt = ipv6_dup_options(newsk, opt); 667 + RCU_INIT_POINTER(newnp->opt, opt); 668 + rcu_read_unlock(); 663 669 664 670 /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname() 665 671 * and getpeername().