summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/sock.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 9f4c4473156a..9c708a5fb751 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1557,6 +1557,12 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
is_charged = sk_filter_charge(newsk, filter);
if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
+ /* We need to make sure that we don't uncharge the new
+ * socket if we couldn't charge it in the first place
+ * as otherwise we uncharge the parent's filter.
+ */
+ if (!is_charged)
+ RCU_INIT_POINTER(newsk->sk_filter, NULL);
/* It is still raw copy of parent, so invalidate
* destructor and make plain sk_free() */
newsk->sk_destruct = NULL;