summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorMatt Bobrowski <mattbobrowski@google.com>2026-07-09 02:53:16 +0000
committerDaniel Borkmann <daniel@iogearbox.net>2026-07-09 18:44:16 +0200
commit7cbd0c4cebe4c9f678d15e6b9ba975e1155a107f (patch)
tree1202aec41ddd9c9f7809611d39435d9177c2a785 /net/core
parent2c7c88a412aa6d09cd04b414211b4ef8553b5309 (diff)
bpf: Fix UAF in sock clone early bailouts
Similar to recent commit 9b51a6155d14 ("bpf,fork: wipe ->bpf_storage before bailouts that access it"), sk_clone() performs an initial shallow copy of the socket field ->sk_bpf_storage via sock_copy() for the cloned socket newsk. If sk_clone() bails out early (e.g. if sk_filter_charge() fails) prior to calling bpf_sk_storage_clone(), newsk->sk_bpf_storage still points to the parent socket's BPF local storage. When newsk is subsequently freed via sk_free(), the deallocation path (__sk_destruct() -> bpf_sk_storage_free()) destroys the parent socket's BPF local storage, leading to a use-after-free (UAF) on the parent socket. Fix this by resetting newsk->sk_bpf_storage to NULL immediately after sock_copy() in sk_clone(), and remove the now redundant initialization from bpf_sk_storage_clone(). Fixes: 6ac99e8f23d4 ("bpf: Introduce bpf sk local storage") Fixes: f12dd75959b0 ("bpf: net: Set sk_bpf_storage back to NULL for cloned sk") Signed-off-by: Matt Bobrowski <mattbobrowski@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20260709025316.999913-1-mattbobrowski@google.com
Diffstat (limited to 'net/core')
-rw-r--r--net/core/bpf_sk_storage.c2
-rw-r--r--net/core/sock.c3
2 files changed, 3 insertions, 2 deletions
diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
index ecd659f79fd4..1d295a8769fa 100644
--- a/net/core/bpf_sk_storage.c
+++ b/net/core/bpf_sk_storage.c
@@ -158,8 +158,6 @@ int bpf_sk_storage_clone(const struct sock *sk, struct sock *newsk)
struct bpf_local_storage_elem *selem;
int ret = 0;
- RCU_INIT_POINTER(newsk->sk_bpf_storage, NULL);
-
rcu_read_lock_dont_migrate();
sk_storage = rcu_dereference(sk->sk_bpf_storage);
diff --git a/net/core/sock.c b/net/core/sock.c
index 8a59bfaa8096..498a57f34f5b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2492,6 +2492,9 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority,
sock_copy(newsk, sk);
newsk->sk_prot_creator = prot;
+#ifdef CONFIG_BPF_SYSCALL
+ RCU_INIT_POINTER(newsk->sk_bpf_storage, NULL);
+#endif
/* SANITY */
if (likely(newsk->sk_net_refcnt)) {