aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/sock.c')
-rw-r--r--net/core/sock.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 9b7b6bbb2a23..23953b741a41 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1654,6 +1654,8 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
1654 1654
1655 sock_copy(newsk, sk); 1655 sock_copy(newsk, sk);
1656 1656
1657 newsk->sk_prot_creator = sk->sk_prot;
1658
1657 /* SANITY */ 1659 /* SANITY */
1658 if (likely(newsk->sk_net_refcnt)) 1660 if (likely(newsk->sk_net_refcnt))
1659 get_net(sock_net(newsk)); 1661 get_net(sock_net(newsk));
@@ -1682,13 +1684,16 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
1682 1684
1683 sock_reset_flag(newsk, SOCK_DONE); 1685 sock_reset_flag(newsk, SOCK_DONE);
1684 1686
1685 filter = rcu_dereference_protected(newsk->sk_filter, 1); 1687 rcu_read_lock();
1688 filter = rcu_dereference(sk->sk_filter);
1686 if (filter != NULL) 1689 if (filter != NULL)
1687 /* though it's an empty new sock, the charging may fail 1690 /* though it's an empty new sock, the charging may fail
1688 * if sysctl_optmem_max was changed between creation of 1691 * if sysctl_optmem_max was changed between creation of
1689 * original socket and cloning 1692 * original socket and cloning
1690 */ 1693 */
1691 is_charged = sk_filter_charge(newsk, filter); 1694 is_charged = sk_filter_charge(newsk, filter);
1695 RCU_INIT_POINTER(newsk->sk_filter, filter);
1696 rcu_read_unlock();
1692 1697
1693 if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) { 1698 if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
1694 /* We need to make sure that we don't uncharge the new 1699 /* We need to make sure that we don't uncharge the new