From 3c3d2c09ec4e11bf7f5419163643b3b02d3f5add Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Thu, 13 Aug 2026 14:41:59 +0200 Subject: [PATCH] bpf: Extract shared reqsk-to-listener upgrade __bpf_sk_lookup() and bpf_sk_lookup() duplicate the same sk_to_full_sk() reqsk-to-listener upgrade. Extract it into a helper. Leave the currently unreachable WARN_ONCE as a defensive assert. No functional change. Signed-off-by: Michal Luczaj Signed-off-by: Daniel Borkmann Reviewed-by: Emil Tsalapatis Reviewed-by: Jakub Sitnicki Link: https://lore.kernel.org/bpf/20260813-sockmap-lookup-get-ref-v1-1-31f5d55f44ac@rbox.co --- net/core/filter.c | 62 ++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 3423734124a5..79cbef41af59 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7167,6 +7167,28 @@ __bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, return sk; } +static struct sock * +bpf_sk_lookup_full_sk(struct sock *sk) +{ + struct sock *sk2 = sk_to_full_sk(sk); + + /* + * sk_to_full_sk() may return sk->rsk_listener, make sure the original + * sk sock refcnt is decremented to prevent a request_sock leak. + */ + if (sk2 != sk) { + sock_gen_put(sk); + /* Ensure there is no need to bump sk2 refcnt. */ + if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) { + WARN_ONCE(1, "Found non-RCU, unreferenced socket!"); + return NULL; + } + sk = sk2; + } + + return sk; +} + static struct sock * __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id, @@ -7175,24 +7197,8 @@ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto, netns_id, flags, sdif); - - if (sk) { - struct sock *sk2 = sk_to_full_sk(sk); - - /* sk_to_full_sk() may return (sk)->rsk_listener, so make sure the original sk - * sock refcnt is decremented to prevent a request_sock leak. - */ - if (sk2 != sk) { - sock_gen_put(sk); - /* Ensure there is no need to bump sk2 refcnt */ - if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) { - WARN_ONCE(1, "Found non-RCU, unreferenced socket!"); - return NULL; - } - sk = sk2; - } - } - + if (sk) + sk = bpf_sk_lookup_full_sk(sk); return sk; } @@ -7221,24 +7227,8 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, { struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id, flags); - - if (sk) { - struct sock *sk2 = sk_to_full_sk(sk); - - /* sk_to_full_sk() may return (sk)->rsk_listener, so make sure the original sk - * sock refcnt is decremented to prevent a request_sock leak. - */ - if (sk2 != sk) { - sock_gen_put(sk); - /* Ensure there is no need to bump sk2 refcnt */ - if (unlikely(sk2 && !sock_flag(sk2, SOCK_RCU_FREE))) { - WARN_ONCE(1, "Found non-RCU, unreferenced socket!"); - return NULL; - } - sk = sk2; - } - } - + if (sk) + sk = bpf_sk_lookup_full_sk(sk); return sk; }