diff options
Diffstat (limited to 'net/core/sock.c')
| -rw-r--r-- | net/core/sock.c | 7 | 
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)  		sock_copy(newsk, sk); +		newsk->sk_prot_creator = sk->sk_prot; +  		/* SANITY */  		if (likely(newsk->sk_net_refcnt))  			get_net(sock_net(newsk)); @@ -1682,13 +1684,16 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)  		sock_reset_flag(newsk, SOCK_DONE); -		filter = rcu_dereference_protected(newsk->sk_filter, 1); +		rcu_read_lock(); +		filter = rcu_dereference(sk->sk_filter);  		if (filter != NULL)  			/* though it's an empty new sock, the charging may fail  			 * if sysctl_optmem_max was changed between creation of  			 * original socket and cloning  			 */  			is_charged = sk_filter_charge(newsk, filter); +		RCU_INIT_POINTER(newsk->sk_filter, filter); +		rcu_read_unlock();  		if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {  			/* We need to make sure that we don't uncharge the new | 
