--- x/include/net/sock.h +++ y/include/net/sock.h @@ -581,6 +581,11 @@ static inline bool sk_user_data_is_nocop return ((uintptr_t)sk->sk_user_data & SK_USER_DATA_NOCOPY); } +static inline bool sk_user_data_is_psock(const struct sock *sk) +{ + return ((uintptr_t)sk->sk_user_data & SK_USER_DATA_PSOCK); +} + #define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data))) /** --- x/net/core/sock.c +++ y/net/core/sock.c @@ -2316,6 +2316,7 @@ struct sock *sk_clone_lock(const struct RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL); if (bpf_sk_storage_clone(sk, newsk)) { +err: sk_free_unlock_clone(newsk); newsk = NULL; goto out; @@ -2324,8 +2325,11 @@ struct sock *sk_clone_lock(const struct /* Clear sk_user_data if parent had the pointer tagged * as not suitable for copying when cloning. */ - if (sk_user_data_is_nocopy(newsk)) + if (sk_user_data_is_nocopy(newsk)) { + if (sk_user_data_is_psock(newsk)) + goto err; newsk->sk_user_data = NULL; + } newsk->sk_err = 0; newsk->sk_err_soft = 0;