mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
bpf: Fix UAF in sock clone early bailouts
Similar to recent commit9b51a6155d("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:6ac99e8f23("bpf: Introduce bpf sk local storage") Fixes:f12dd75959("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
This commit is contained in:
committed by
Daniel Borkmann
parent
2c7c88a412
commit
7cbd0c4ceb
@@ -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);
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user