* [PATCH net] udp: drop secpath before storing an skb in a receive queue
@ 2025-10-14 6:04 Eric Dumazet
2025-10-14 6:37 ` Sabrina Dubroca
0 siblings, 1 reply; 17+ messages in thread
From: Eric Dumazet @ 2025-10-14 6:04 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Willem de Bruijn, netdev, eric.dumazet,
Eric Dumazet, Michal Kubecek, Sabrina Dubroca
Michal reported and bisected an issue after recent adoption
of skb_attempt_defer_free() in UDP.
We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f
("tcp: drop secpath at the same time as we currently drop dst")
Many thanks to Michal and Sabrina.
Fixes: 6471658dc66c ("udp: use skb_attempt_defer_free()")
Reported-and-bisected-by: Michal Kubecek <mkubecek@suse.cz>
Closes: https://lore.kernel.org/netdev/gpjh4lrotyephiqpuldtxxizrsg6job7cvhiqrw72saz2ubs3h@g6fgbvexgl3r/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Sabrina Dubroca <sd@queasysnail.net>
---
net/ipv4/udp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 95241093b7f0..3f05ee70029c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1709,6 +1709,8 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
int dropcount;
int nb = 0;
+ secpath_reset(skb);
+
rmem = atomic_read(&sk->sk_rmem_alloc);
rcvbuf = READ_ONCE(sk->sk_rcvbuf);
size = skb->truesize;
--
2.51.0.788.g6d19910ace-goog
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 6:04 [PATCH net] udp: drop secpath before storing an skb in a receive queue Eric Dumazet @ 2025-10-14 6:37 ` Sabrina Dubroca 2025-10-14 6:54 ` Eric Dumazet 2025-10-14 7:32 ` Paolo Abeni 0 siblings, 2 replies; 17+ messages in thread From: Sabrina Dubroca @ 2025-10-14 6:37 UTC (permalink / raw) To: Eric Dumazet Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > Michal reported and bisected an issue after recent adoption > of skb_attempt_defer_free() in UDP. > > We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > ("tcp: drop secpath at the same time as we currently drop dst") I'm not convinced this is the same bug. The TCP one was a "leaked" reference (delayed put). This looks more like a double put/missing hold to me (we get to the destroy path without having done the proper delete, which would set XFRM_STATE_DEAD). And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete x->tunnel as we delete x"). > Many thanks to Michal and Sabrina. > > Fixes: 6471658dc66c ("udp: use skb_attempt_defer_free()") > Reported-and-bisected-by: Michal Kubecek <mkubecek@suse.cz> > Closes: https://lore.kernel.org/netdev/gpjh4lrotyephiqpuldtxxizrsg6job7cvhiqrw72saz2ubs3h@g6fgbvexgl3r/ > Signed-off-by: Eric Dumazet <edumazet@google.com> > Cc: Sabrina Dubroca <sd@queasysnail.net> > --- > net/ipv4/udp.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..3f05ee70029c 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1709,6 +1709,8 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) > int dropcount; > int nb = 0; > > + secpath_reset(skb); See also the comment for udp_try_make_stateless: /* all head states (dst, sk, nf conntrack) except skb extensions are * cleared by udp_rcv(). * * We need to preserve secpath, if present, to eventually process * IP_CMSG_PASSSEC at recvmsg() time. * * Other extensions can be cleared. */ It looks like this patch would re-introduce the problem fixed by dce4551cb2ad ("udp: preserve head state for IP_CMSG_PASSSEC"). > + > rmem = atomic_read(&sk->sk_rmem_alloc); > rcvbuf = READ_ONCE(sk->sk_rcvbuf); > size = skb->truesize; > -- > 2.51.0.788.g6d19910ace-goog > -- Sabrina ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 6:37 ` Sabrina Dubroca @ 2025-10-14 6:54 ` Eric Dumazet 2025-10-14 7:32 ` Paolo Abeni 1 sibling, 0 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 6:54 UTC (permalink / raw) To: Sabrina Dubroca Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Mon, Oct 13, 2025 at 11:37 PM Sabrina Dubroca <sd@queasysnail.net> wrote: > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > Michal reported and bisected an issue after recent adoption > > of skb_attempt_defer_free() in UDP. > > > > We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > ("tcp: drop secpath at the same time as we currently drop dst") > > I'm not convinced this is the same bug. The TCP one was a "leaked" > reference (delayed put). This looks more like a double put/missing > hold to me (we get to the destroy path without having done the proper > delete, which would set XFRM_STATE_DEAD). > Hmm, this was bisected to use of skb_attempt_defer_free(), surely holding xfrm in a per-cpu queue looks the same to me. We also had recent syzbot reports hinting at that. > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > x->tunnel as we delete x"). > > > Many thanks to Michal and Sabrina. > > > > Fixes: 6471658dc66c ("udp: use skb_attempt_defer_free()") > > Reported-and-bisected-by: Michal Kubecek <mkubecek@suse.cz> > > Closes: https://lore.kernel.org/netdev/gpjh4lrotyephiqpuldtxxizrsg6job7cvhiqrw72saz2ubs3h@g6fgbvexgl3r/ > > Signed-off-by: Eric Dumazet <edumazet@google.com> > > Cc: Sabrina Dubroca <sd@queasysnail.net> > > --- > > net/ipv4/udp.c | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > index 95241093b7f0..3f05ee70029c 100644 > > --- a/net/ipv4/udp.c > > +++ b/net/ipv4/udp.c > > @@ -1709,6 +1709,8 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) > > int dropcount; > > int nb = 0; > > > > + secpath_reset(skb); > > See also the comment for udp_try_make_stateless: > > /* all head states (dst, sk, nf conntrack) except skb extensions are > * cleared by udp_rcv(). > * > * We need to preserve secpath, if present, to eventually process > * IP_CMSG_PASSSEC at recvmsg() time. > * > * Other extensions can be cleared. > */ > > > It looks like this patch would re-introduce the problem fixed by > dce4551cb2ad ("udp: preserve head state for IP_CMSG_PASSSEC"). Arg, I tried to not slow down the consumer part, too bad for XFRM then. What about then : diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 95241093b7f0..ac45e4056c51 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1853,6 +1853,7 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) if (!skb_shared(skb)) { if (unlikely(udp_skb_has_head_state(skb))) skb_release_head_state(skb); + secpath_reset(skb); skb_attempt_defer_free(skb); return; } ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 6:37 ` Sabrina Dubroca 2025-10-14 6:54 ` Eric Dumazet @ 2025-10-14 7:32 ` Paolo Abeni 2025-10-14 7:43 ` Eric Dumazet 2025-10-14 7:45 ` Sabrina Dubroca 1 sibling, 2 replies; 17+ messages in thread From: Paolo Abeni @ 2025-10-14 7:32 UTC (permalink / raw) To: Sabrina Dubroca, Eric Dumazet Cc: David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: >> Michal reported and bisected an issue after recent adoption >> of skb_attempt_defer_free() in UDP. >> >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f >> ("tcp: drop secpath at the same time as we currently drop dst") > > I'm not convinced this is the same bug. The TCP one was a "leaked" > reference (delayed put). This looks more like a double put/missing > hold to me (we get to the destroy path without having done the proper > delete, which would set XFRM_STATE_DEAD). > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > x->tunnel as we delete x"). I think Sabrina is right. If the skb carries a secpath, UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be called by skb_consume_udp(). skb_ext_put() does not clear skb->extensions nor ext->refcnt, if skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), the skb will go through again skb_release_head_state(), with a double free. I think something alike the following (completely untested) should work: --- diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 95241093b7f0..4a308fd6aa6c 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) sk_peek_offset_bwd(sk, len); if (!skb_shared(skb)) { - if (unlikely(udp_skb_has_head_state(skb))) + if (unlikely(udp_skb_has_head_state(skb))) { skb_release_head_state(skb); + skb->active_extensions = 0; + } skb_attempt_defer_free(skb); return; } --- ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 7:32 ` Paolo Abeni @ 2025-10-14 7:43 ` Eric Dumazet 2025-10-14 8:01 ` Eric Dumazet 2025-10-14 7:45 ` Sabrina Dubroca 1 sibling, 1 reply; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 7:43 UTC (permalink / raw) To: Paolo Abeni Cc: Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > >> Michal reported and bisected an issue after recent adoption > >> of skb_attempt_defer_free() in UDP. > >> > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > reference (delayed put). This looks more like a double put/missing > > hold to me (we get to the destroy path without having done the proper > > delete, which would set XFRM_STATE_DEAD). > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > x->tunnel as we delete x"). > > I think Sabrina is right. If the skb carries a secpath, > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > called by skb_consume_udp(). > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > the skb will go through again skb_release_head_state(), with a double free. > > I think something alike the following (completely untested) should work: > --- > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..4a308fd6aa6c 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > + if (unlikely(udp_skb_has_head_state(skb))) { > skb_release_head_state(skb); > + skb->active_extensions = 0; Wait, what, skb_ext_put() can not be called twice ? Because we prefer not dirtying skb in skb_release_head_state() ? Perhaps add a big comment in skb_release_head_state() to avoid mistakes. diff --git a/net/core/skbuff.c b/net/core/skbuff.c index bc12790017b0b5c0be99f8fb9d362b3730fa4eb0..8d274ddd54ad4c59cc29f821fc371c89052bf875 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1141,6 +1141,10 @@ void skb_release_head_state(struct sk_buff *skb) #if IS_ENABLED(CONFIG_NF_CONNTRACK) nf_conntrack_put(skb_nfct(skb)); #endif + + /* Note: we do not call skb_ext_reset() to avoid dirtying + * a cache line. Callers might have to clear skb->active_extensions. + */ skb_ext_put(skb); } ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 7:43 ` Eric Dumazet @ 2025-10-14 8:01 ` Eric Dumazet 2025-10-14 8:06 ` Eric Dumazet 0 siblings, 1 reply; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 8:01 UTC (permalink / raw) To: Paolo Abeni Cc: Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Tue, Oct 14, 2025 at 12:43 AM Eric Dumazet <edumazet@google.com> wrote: > > On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > >> Michal reported and bisected an issue after recent adoption > > >> of skb_attempt_defer_free() in UDP. > > >> > > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > > reference (delayed put). This looks more like a double put/missing > > > hold to me (we get to the destroy path without having done the proper > > > delete, which would set XFRM_STATE_DEAD). > > > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > > x->tunnel as we delete x"). > > > > I think Sabrina is right. If the skb carries a secpath, > > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > > called by skb_consume_udp(). > > > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > > the skb will go through again skb_release_head_state(), with a double free. > > > > I think something alike the following (completely untested) should work: > > --- > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > index 95241093b7f0..4a308fd6aa6c 100644 > > --- a/net/ipv4/udp.c > > +++ b/net/ipv4/udp.c > > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > > sk_buff *skb, int len) > > sk_peek_offset_bwd(sk, len); > > > > if (!skb_shared(skb)) { > > - if (unlikely(udp_skb_has_head_state(skb))) > > + if (unlikely(udp_skb_has_head_state(skb))) { > > skb_release_head_state(skb); > > + skb->active_extensions = 0; We probably also want to clear CONNTRACK state as well. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:01 ` Eric Dumazet @ 2025-10-14 8:06 ` Eric Dumazet 2025-10-14 8:27 ` Eric Dumazet 2025-10-14 8:28 ` Sabrina Dubroca 0 siblings, 2 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 8:06 UTC (permalink / raw) To: Paolo Abeni Cc: Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Tue, Oct 14, 2025 at 1:01 AM Eric Dumazet <edumazet@google.com> wrote: > > On Tue, Oct 14, 2025 at 12:43 AM Eric Dumazet <edumazet@google.com> wrote: > > > > On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > > > > > > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > > >> Michal reported and bisected an issue after recent adoption > > > >> of skb_attempt_defer_free() in UDP. > > > >> > > > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > > > reference (delayed put). This looks more like a double put/missing > > > > hold to me (we get to the destroy path without having done the proper > > > > delete, which would set XFRM_STATE_DEAD). > > > > > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > > > x->tunnel as we delete x"). > > > > > > I think Sabrina is right. If the skb carries a secpath, > > > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > > > called by skb_consume_udp(). > > > > > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > > > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > > > the skb will go through again skb_release_head_state(), with a double free. > > > > > > I think something alike the following (completely untested) should work: > > > --- > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > > index 95241093b7f0..4a308fd6aa6c 100644 > > > --- a/net/ipv4/udp.c > > > +++ b/net/ipv4/udp.c > > > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > > > sk_buff *skb, int len) > > > sk_peek_offset_bwd(sk, len); > > > > > > if (!skb_shared(skb)) { > > > - if (unlikely(udp_skb_has_head_state(skb))) > > > + if (unlikely(udp_skb_has_head_state(skb))) { > > > skb_release_head_state(skb); > > > + skb->active_extensions = 0; > > We probably also want to clear CONNTRACK state as well. Perhaps not use skb_release_head_state() ? We know there is no dst, and no destructor. diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 95241093b7f0..98628486c4c5 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) sk_peek_offset_bwd(sk, len); if (!skb_shared(skb)) { - if (unlikely(udp_skb_has_head_state(skb))) - skb_release_head_state(skb); + if (unlikely(udp_skb_has_head_state(skb))) { + nf_reset_ct(skb); + skb_ext_reset(skb); + } skb_attempt_defer_free(skb); return; } ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:06 ` Eric Dumazet @ 2025-10-14 8:27 ` Eric Dumazet 2025-10-14 8:55 ` Paolo Abeni 2025-10-14 11:20 ` Michal Kubecek 2025-10-14 8:28 ` Sabrina Dubroca 1 sibling, 2 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 8:27 UTC (permalink / raw) To: Paolo Abeni Cc: Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Tue, Oct 14, 2025 at 1:06 AM Eric Dumazet <edumazet@google.com> wrote: > > On Tue, Oct 14, 2025 at 1:01 AM Eric Dumazet <edumazet@google.com> wrote: > > > > On Tue, Oct 14, 2025 at 12:43 AM Eric Dumazet <edumazet@google.com> wrote: > > > > > > On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > > > > > > > > > > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > > > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > > > >> Michal reported and bisected an issue after recent adoption > > > > >> of skb_attempt_defer_free() in UDP. > > > > >> > > > > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > > > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > > > > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > > > > reference (delayed put). This looks more like a double put/missing > > > > > hold to me (we get to the destroy path without having done the proper > > > > > delete, which would set XFRM_STATE_DEAD). > > > > > > > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > > > > x->tunnel as we delete x"). > > > > > > > > I think Sabrina is right. If the skb carries a secpath, > > > > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > > > > called by skb_consume_udp(). > > > > > > > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > > > > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > > > > the skb will go through again skb_release_head_state(), with a double free. > > > > > > > > I think something alike the following (completely untested) should work: > > > > --- > > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > > > index 95241093b7f0..4a308fd6aa6c 100644 > > > > --- a/net/ipv4/udp.c > > > > +++ b/net/ipv4/udp.c > > > > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > > > > sk_buff *skb, int len) > > > > sk_peek_offset_bwd(sk, len); > > > > > > > > if (!skb_shared(skb)) { > > > > - if (unlikely(udp_skb_has_head_state(skb))) > > > > + if (unlikely(udp_skb_has_head_state(skb))) { > > > > skb_release_head_state(skb); > > > > + skb->active_extensions = 0; > > > > We probably also want to clear CONNTRACK state as well. > > Perhaps not use skb_release_head_state() ? > > We know there is no dst, and no destructor. > An no conntrack either from UDP diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 95241093b7f0..932c21838b9b 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) sk_peek_offset_bwd(sk, len); if (!skb_shared(skb)) { - if (unlikely(udp_skb_has_head_state(skb))) - skb_release_head_state(skb); + if (unlikely(udp_skb_has_head_state(skb))) { + /* Make sure that skb_release_head_state() will have nothing to do. */ + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); + DEBUG_NET_WARN_ON_ONCE(skb->destructor); + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); + skb_ext_reset(skb); + } skb_attempt_defer_free(skb); return; } ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:27 ` Eric Dumazet @ 2025-10-14 8:55 ` Paolo Abeni 2025-10-14 11:20 ` Michal Kubecek 1 sibling, 0 replies; 17+ messages in thread From: Paolo Abeni @ 2025-10-14 8:55 UTC (permalink / raw) To: Eric Dumazet Cc: Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On 10/14/25 10:27 AM, Eric Dumazet wrote: > On Tue, Oct 14, 2025 at 1:06 AM Eric Dumazet <edumazet@google.com> wrote: >> Perhaps not use skb_release_head_state() ? >> >> We know there is no dst, and no destructor. >> > > An no conntrack either from UDP > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..932c21838b9b 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > - skb_release_head_state(skb); > + if (unlikely(udp_skb_has_head_state(skb))) { > + /* Make sure that skb_release_head_state() > will have nothing to do. */ > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > + skb_ext_reset(skb); > + } > skb_attempt_defer_free(skb); > return; > } LGTM, thanks! /P ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:27 ` Eric Dumazet 2025-10-14 8:55 ` Paolo Abeni @ 2025-10-14 11:20 ` Michal Kubecek 2025-10-14 11:34 ` Eric Dumazet 1 sibling, 1 reply; 17+ messages in thread From: Michal Kubecek @ 2025-10-14 11:20 UTC (permalink / raw) To: Eric Dumazet Cc: Paolo Abeni, Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet [-- Attachment #1: Type: text/plain, Size: 1184 bytes --] On Tue, Oct 14, 2025 at 01:27:13AM GMT, Eric Dumazet wrote: > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..932c21838b9b 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > - skb_release_head_state(skb); > + if (unlikely(udp_skb_has_head_state(skb))) { > + /* Make sure that skb_release_head_state() > will have nothing to do. */ > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > + skb_ext_reset(skb); > + } > skb_attempt_defer_free(skb); > return; > } Tested this version on my system (with DEBUG_NET enabled) and everything seems to work fine so far. Tested-by: Michal Kubecek <mkubecek@suse.cz> Michal [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 11:20 ` Michal Kubecek @ 2025-10-14 11:34 ` Eric Dumazet 2025-10-14 13:18 ` Michal Kubecek 2025-10-14 13:40 ` Florian Westphal 0 siblings, 2 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 11:34 UTC (permalink / raw) To: Michal Kubecek Cc: Paolo Abeni, Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet On Tue, Oct 14, 2025 at 4:20 AM Michal Kubecek <mkubecek@suse.cz> wrote: > > On Tue, Oct 14, 2025 at 01:27:13AM GMT, Eric Dumazet wrote: > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > index 95241093b7f0..932c21838b9b 100644 > > --- a/net/ipv4/udp.c > > +++ b/net/ipv4/udp.c > > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > > sk_buff *skb, int len) > > sk_peek_offset_bwd(sk, len); > > > > if (!skb_shared(skb)) { > > - if (unlikely(udp_skb_has_head_state(skb))) > > - skb_release_head_state(skb); > > + if (unlikely(udp_skb_has_head_state(skb))) { > > + /* Make sure that skb_release_head_state() > > will have nothing to do. */ > > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > > + skb_ext_reset(skb); > > + } > > skb_attempt_defer_free(skb); > > return; > > } > > Tested this version on my system (with DEBUG_NET enabled) and everything > seems to work fine so far. > > Tested-by: Michal Kubecek <mkubecek@suse.cz> Thanks for testing. I will follow Sabrina suggestion and send : diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 95241093b7f0..d66f273f9070 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) sk_peek_offset_bwd(sk, len); if (!skb_shared(skb)) { - if (unlikely(udp_skb_has_head_state(skb))) - skb_release_head_state(skb); + /* Make sure that this skb has no dst, destructor + * or conntracking parts, because it might stay + * in a remote cpu list for a very long time. + */ + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); + DEBUG_NET_WARN_ON_ONCE(skb->destructor); + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); skb_attempt_defer_free(skb); return; } ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 11:34 ` Eric Dumazet @ 2025-10-14 13:18 ` Michal Kubecek 2025-10-14 13:40 ` Florian Westphal 1 sibling, 0 replies; 17+ messages in thread From: Michal Kubecek @ 2025-10-14 13:18 UTC (permalink / raw) To: Eric Dumazet Cc: Paolo Abeni, Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet [-- Attachment #1: Type: text/plain, Size: 2609 bytes --] On Tue, Oct 14, 2025 at 04:34:52AM GMT, Eric Dumazet wrote: > On Tue, Oct 14, 2025 at 4:20 AM Michal Kubecek <mkubecek@suse.cz> wrote: > > > > On Tue, Oct 14, 2025 at 01:27:13AM GMT, Eric Dumazet wrote: > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > > index 95241093b7f0..932c21838b9b 100644 > > > --- a/net/ipv4/udp.c > > > +++ b/net/ipv4/udp.c > > > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > > > sk_buff *skb, int len) > > > sk_peek_offset_bwd(sk, len); > > > > > > if (!skb_shared(skb)) { > > > - if (unlikely(udp_skb_has_head_state(skb))) > > > - skb_release_head_state(skb); > > > + if (unlikely(udp_skb_has_head_state(skb))) { > > > + /* Make sure that skb_release_head_state() > > > will have nothing to do. */ > > > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > > > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > > > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > > > + skb_ext_reset(skb); > > > + } > > > skb_attempt_defer_free(skb); > > > return; > > > } > > > > Tested this version on my system (with DEBUG_NET enabled) and everything > > seems to work fine so far. > > > > Tested-by: Michal Kubecek <mkubecek@suse.cz> > > Thanks for testing. I will follow Sabrina suggestion and send : > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..d66f273f9070 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > - skb_release_head_state(skb); > + /* Make sure that this skb has no dst, destructor > + * or conntracking parts, because it might stay > + * in a remote cpu list for a very long time. > + */ > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > skb_attempt_defer_free(skb); > return; > } Running 6.18-rc1 with this patch right now, everything seems to work as well. Thanks to everyone for quick response. Tested-by: Michal Kubecek <mkubecek@suse.cz> Michal [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 11:34 ` Eric Dumazet 2025-10-14 13:18 ` Michal Kubecek @ 2025-10-14 13:40 ` Florian Westphal 2025-10-14 13:58 ` Eric Dumazet 1 sibling, 1 reply; 17+ messages in thread From: Florian Westphal @ 2025-10-14 13:40 UTC (permalink / raw) To: Eric Dumazet Cc: Michal Kubecek, Paolo Abeni, Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet Eric Dumazet <edumazet@google.com> wrote: > Thanks for testing. I will follow Sabrina suggestion and send : > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..d66f273f9070 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > - skb_release_head_state(skb); > + /* Make sure that this skb has no dst, destructor > + * or conntracking parts, because it might stay > + * in a remote cpu list for a very long time. > + */ > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > skb_attempt_defer_free(skb); Are there cases where we expect to pass skb which violate this to skb_attempt_defer_free()? If no, then maybe move existing checks in skb_attempt_defer_free() up and apped the skb_nfct check there so syzbot can blame other offenders too. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 13:40 ` Florian Westphal @ 2025-10-14 13:58 ` Eric Dumazet 0 siblings, 0 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 13:58 UTC (permalink / raw) To: Florian Westphal Cc: Michal Kubecek, Paolo Abeni, Sabrina Dubroca, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet On Tue, Oct 14, 2025 at 6:40 AM Florian Westphal <fw@strlen.de> wrote: > > Eric Dumazet <edumazet@google.com> wrote: > > Thanks for testing. I will follow Sabrina suggestion and send : > > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > index 95241093b7f0..d66f273f9070 100644 > > --- a/net/ipv4/udp.c > > +++ b/net/ipv4/udp.c > > @@ -1851,8 +1851,13 @@ void skb_consume_udp(struct sock *sk, struct > > sk_buff *skb, int len) > > sk_peek_offset_bwd(sk, len); > > > > if (!skb_shared(skb)) { > > - if (unlikely(udp_skb_has_head_state(skb))) > > - skb_release_head_state(skb); > > + /* Make sure that this skb has no dst, destructor > > + * or conntracking parts, because it might stay > > + * in a remote cpu list for a very long time. > > + */ > > + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); > > + DEBUG_NET_WARN_ON_ONCE(skb->destructor); > > + DEBUG_NET_WARN_ON_ONCE(skb_nfct(skb)); > > skb_attempt_defer_free(skb); > > Are there cases where we expect to pass skb which violate this to > skb_attempt_defer_free()? So far UDP makes sure these fields are cleared. > > If no, then maybe move existing checks in skb_attempt_defer_free() up and > apped the skb_nfct check there so syzbot can blame other offenders too. You are right, I forgot skb_attempt_defer_free() already had: commit e8e1ce8454c9cc8ad2e4422bef346428e52455e3 Author: Eric Dumazet <edumazet@google.com> Date: Fri Apr 21 09:43:53 2023 +0000 net: add debugging checks in skb_attempt_defer_free() Make sure skbs that are stored in softnet_data.defer_list do not have a dst attached. Also make sure the the skb was orphaned. Link: https://lore.kernel.org/netdev/CANn89iJuEVe72bPmEftyEJHLzzN=QNR2yueFjTxYXCEpS5S8HQ@mail.gmail.com/T/ Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0d998806b377..bd815a00d2af 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -6881,6 +6881,9 @@ nodefer: __kfree_skb(skb); return; } + DEBUG_NET_WARN_ON_ONCE(skb_dst(skb)); + DEBUG_NET_WARN_ON_ONCE(skb->destructor); + sd = &per_cpu(softnet_data, cpu); defer_max = READ_ONCE(sysctl_skb_defer_max); if (READ_ONCE(sd->defer_count) >= defer_max) ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:06 ` Eric Dumazet 2025-10-14 8:27 ` Eric Dumazet @ 2025-10-14 8:28 ` Sabrina Dubroca 2025-10-14 8:33 ` Eric Dumazet 1 sibling, 1 reply; 17+ messages in thread From: Sabrina Dubroca @ 2025-10-14 8:28 UTC (permalink / raw) To: Eric Dumazet Cc: Paolo Abeni, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek 2025-10-14, 01:06:04 -0700, Eric Dumazet wrote: > On Tue, Oct 14, 2025 at 1:01 AM Eric Dumazet <edumazet@google.com> wrote: > > > > On Tue, Oct 14, 2025 at 12:43 AM Eric Dumazet <edumazet@google.com> wrote: > > > > > > On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > > > > > > > > > > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > > > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > > > >> Michal reported and bisected an issue after recent adoption > > > > >> of skb_attempt_defer_free() in UDP. > > > > >> > > > > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > > > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > > > > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > > > > reference (delayed put). This looks more like a double put/missing > > > > > hold to me (we get to the destroy path without having done the proper > > > > > delete, which would set XFRM_STATE_DEAD). > > > > > > > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > > > > x->tunnel as we delete x"). > > > > > > > > I think Sabrina is right. If the skb carries a secpath, > > > > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > > > > called by skb_consume_udp(). > > > > > > > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > > > > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > > > > the skb will go through again skb_release_head_state(), with a double free. > > > > > > > > I think something alike the following (completely untested) should work: > > > > --- > > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > > > index 95241093b7f0..4a308fd6aa6c 100644 > > > > --- a/net/ipv4/udp.c > > > > +++ b/net/ipv4/udp.c > > > > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > > > > sk_buff *skb, int len) > > > > sk_peek_offset_bwd(sk, len); > > > > > > > > if (!skb_shared(skb)) { > > > > - if (unlikely(udp_skb_has_head_state(skb))) > > > > + if (unlikely(udp_skb_has_head_state(skb))) { > > > > skb_release_head_state(skb); > > > > + skb->active_extensions = 0; > > > > We probably also want to clear CONNTRACK state as well. > > Perhaps not use skb_release_head_state() ? > > We know there is no dst, and no destructor. Then, do we need to do anything before calling skb_attempt_defer_free()? skb_attempt_defer_free() only wants no dst and no destructor, and the secpath issue that we dealt with in TCP is not a problem anymore. Can we just drop the udp_skb_has_head_state() special handling and simply call skb_attempt_defer_free()? > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..98628486c4c5 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > - skb_release_head_state(skb); > + if (unlikely(udp_skb_has_head_state(skb))) { > + nf_reset_ct(skb); > + skb_ext_reset(skb); > + } > skb_attempt_defer_free(skb); > return; > } -- Sabrina ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 8:28 ` Sabrina Dubroca @ 2025-10-14 8:33 ` Eric Dumazet 0 siblings, 0 replies; 17+ messages in thread From: Eric Dumazet @ 2025-10-14 8:33 UTC (permalink / raw) To: Sabrina Dubroca Cc: Paolo Abeni, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek On Tue, Oct 14, 2025 at 1:28 AM Sabrina Dubroca <sd@queasysnail.net> wrote: > > 2025-10-14, 01:06:04 -0700, Eric Dumazet wrote: > > On Tue, Oct 14, 2025 at 1:01 AM Eric Dumazet <edumazet@google.com> wrote: > > > > > > On Tue, Oct 14, 2025 at 12:43 AM Eric Dumazet <edumazet@google.com> wrote: > > > > > > > > On Tue, Oct 14, 2025 at 12:32 AM Paolo Abeni <pabeni@redhat.com> wrote: > > > > > > > > > > > > > > > > > > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > > > > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > > > > > >> Michal reported and bisected an issue after recent adoption > > > > > >> of skb_attempt_defer_free() in UDP. > > > > > >> > > > > > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > > > > > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > > > > > > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > > > > > reference (delayed put). This looks more like a double put/missing > > > > > > hold to me (we get to the destroy path without having done the proper > > > > > > delete, which would set XFRM_STATE_DEAD). > > > > > > > > > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > > > > > x->tunnel as we delete x"). > > > > > > > > > > I think Sabrina is right. If the skb carries a secpath, > > > > > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > > > > > called by skb_consume_udp(). > > > > > > > > > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > > > > > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > > > > > the skb will go through again skb_release_head_state(), with a double free. > > > > > > > > > > I think something alike the following (completely untested) should work: > > > > > --- > > > > > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > > > > > index 95241093b7f0..4a308fd6aa6c 100644 > > > > > --- a/net/ipv4/udp.c > > > > > +++ b/net/ipv4/udp.c > > > > > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > > > > > sk_buff *skb, int len) > > > > > sk_peek_offset_bwd(sk, len); > > > > > > > > > > if (!skb_shared(skb)) { > > > > > - if (unlikely(udp_skb_has_head_state(skb))) > > > > > + if (unlikely(udp_skb_has_head_state(skb))) { > > > > > skb_release_head_state(skb); > > > > > + skb->active_extensions = 0; > > > > > > We probably also want to clear CONNTRACK state as well. > > > > Perhaps not use skb_release_head_state() ? > > > > We know there is no dst, and no destructor. > > Then, do we need to do anything before calling skb_attempt_defer_free()? > skb_attempt_defer_free() only wants no dst and no destructor, and the > secpath issue that we dealt with in TCP is not a problem anymore. > > Can we just drop the udp_skb_has_head_state() special handling and > simply call skb_attempt_defer_free()? Good point ! I need a second cup of coffee ! ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] udp: drop secpath before storing an skb in a receive queue 2025-10-14 7:32 ` Paolo Abeni 2025-10-14 7:43 ` Eric Dumazet @ 2025-10-14 7:45 ` Sabrina Dubroca 1 sibling, 0 replies; 17+ messages in thread From: Sabrina Dubroca @ 2025-10-14 7:45 UTC (permalink / raw) To: Paolo Abeni Cc: Eric Dumazet, David S . Miller, Jakub Kicinski, Simon Horman, Willem de Bruijn, netdev, eric.dumazet, Michal Kubecek 2025-10-14, 09:32:09 +0200, Paolo Abeni wrote: > > > On 10/14/25 8:37 AM, Sabrina Dubroca wrote: > > 2025-10-14, 06:04:54 +0000, Eric Dumazet wrote: > >> Michal reported and bisected an issue after recent adoption > >> of skb_attempt_defer_free() in UDP. > >> > >> We had the same issue for TCP, that Sabrina fixed in commit 9b6412e6979f > >> ("tcp: drop secpath at the same time as we currently drop dst") > > > > I'm not convinced this is the same bug. The TCP one was a "leaked" > > reference (delayed put). This looks more like a double put/missing > > hold to me (we get to the destroy path without having done the proper > > delete, which would set XFRM_STATE_DEAD). > > > > And this shouldn't be an issue after b441cf3f8c4b ("xfrm: delete > > x->tunnel as we delete x"). > > I think Sabrina is right. If the skb carries a secpath, > UDP_SKB_IS_STATELESS is not set, and skb_release_head_state() will be > called by skb_consume_udp(). > > skb_ext_put() does not clear skb->extensions nor ext->refcnt, if > skb_attempt_defer_free() enters the slow path (kfree_skb_napi_cache()), > the skb will go through again skb_release_head_state(), with a double free. Thanks Paolo, I was going down the same path, you got there faster :) > I think something alike the following (completely untested) should work: > --- > diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c > index 95241093b7f0..4a308fd6aa6c 100644 > --- a/net/ipv4/udp.c > +++ b/net/ipv4/udp.c > @@ -1851,8 +1851,10 @@ void skb_consume_udp(struct sock *sk, struct > sk_buff *skb, int len) > sk_peek_offset_bwd(sk, len); > > if (!skb_shared(skb)) { > - if (unlikely(udp_skb_has_head_state(skb))) > + if (unlikely(udp_skb_has_head_state(skb))) { > skb_release_head_state(skb); > + skb->active_extensions = 0; > + } > skb_attempt_defer_free(skb); > return; > } -- Sabrina ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2025-10-14 13:58 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-10-14 6:04 [PATCH net] udp: drop secpath before storing an skb in a receive queue Eric Dumazet 2025-10-14 6:37 ` Sabrina Dubroca 2025-10-14 6:54 ` Eric Dumazet 2025-10-14 7:32 ` Paolo Abeni 2025-10-14 7:43 ` Eric Dumazet 2025-10-14 8:01 ` Eric Dumazet 2025-10-14 8:06 ` Eric Dumazet 2025-10-14 8:27 ` Eric Dumazet 2025-10-14 8:55 ` Paolo Abeni 2025-10-14 11:20 ` Michal Kubecek 2025-10-14 11:34 ` Eric Dumazet 2025-10-14 13:18 ` Michal Kubecek 2025-10-14 13:40 ` Florian Westphal 2025-10-14 13:58 ` Eric Dumazet 2025-10-14 8:28 ` Sabrina Dubroca 2025-10-14 8:33 ` Eric Dumazet 2025-10-14 7:45 ` Sabrina Dubroca
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).