* [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore
@ 2025-08-18 15:40 Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 1/7] net: Add " Stanislav Fomichev
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
To diagnose and prevent issues similar to [0], emit warning
(CONFIG_DEBUG_NET) from skb_dst_set and skb_dst_set_noref when
overwriting non-null reference-counted entry. Two new helpers
are added to handle special cases where the entry needs to be
reset and restored: skb_dstref_steal/skb_dstref_restore. The bulk of
the patches in the series converts manual _skb_refst manipulations
to these new helpers.
0: https://lore.kernel.org/netdev/20250723224625.1340224-1-sdf@fomichev.me/T/#u
v2:
- rename to skb_dstref_steal/skb_dstref_restore (Jakub)
- fix kdoc (Jakub)
Stanislav Fomichev (7):
net: Add skb_dstref_steal and skb_dstref_restore
xfrm: Switch to skb_dstref_steal to clear dst_entry
netfilter: Switch to skb_dstref_steal to clear dst_entry
net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input
callers
staging: octeon: Convert to skb_dst_drop
chtls: Convert to skb_dst_reset
net: Add skb_dst_check_unset
.../chelsio/inline_crypto/chtls/chtls_cm.c | 10 ++---
.../chelsio/inline_crypto/chtls/chtls_cm.h | 4 +-
.../chelsio/inline_crypto/chtls/chtls_io.c | 2 +-
drivers/staging/octeon/ethernet-tx.c | 3 +-
include/linux/skbuff.h | 41 +++++++++++++++++++
net/ipv4/icmp.c | 7 ++--
net/ipv4/ip_options.c | 5 +--
net/ipv4/netfilter.c | 5 ++-
net/ipv6/netfilter.c | 5 ++-
net/xfrm/xfrm_policy.c | 10 ++++-
10 files changed, 72 insertions(+), 20 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH net-next v2 1/7] net: Add skb_dstref_steal and skb_dstref_restore
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry Stanislav Fomichev
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set to prevent potential leaks. There
are few places that still manually manage dst_entry not using
the helpers. Convert them to the following new helpers:
- skb_dstref_steal that resets dst_entry and returns previous dst_entry
value
- skb_dstref_restore that restores dst_entry previously reset via
skb_dstref_steal
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
include/linux/skbuff.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 14b923ddb6df..7538ca507ee9 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1159,6 +1159,38 @@ static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
return (struct dst_entry *)(skb->_skb_refdst & SKB_DST_PTRMASK);
}
+/**
+ * skb_dstref_steal() - return current dst_entry value and clear it
+ * @skb: buffer
+ *
+ * Resets skb dst_entry without adjusting its reference count. Useful in
+ * cases where dst_entry needs to be temporarily reset and restored.
+ * Note that the returned value cannot be used directly because it
+ * might contain SKB_DST_NOREF bit.
+ *
+ * When in doubt, prefer skb_dst_drop() over skb_dstref_steal() to correctly
+ * handle dst_entry reference counting.
+ *
+ * Returns: original skb dst_entry.
+ */
+static inline unsigned long skb_dstref_steal(struct sk_buff *skb)
+{
+ unsigned long refdst = skb->_skb_refdst;
+
+ skb->_skb_refdst = 0;
+ return refdst;
+}
+
+/**
+ * skb_dstref_restore() - restore skb dst_entry removed via skb_dstref_steal()
+ * @skb: buffer
+ * @refdst: dst entry from a call to skb_dstref_steal()
+ */
+static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
+{
+ skb->_skb_refdst = refdst;
+}
+
/**
* skb_dst_set - sets skb dst
* @skb: buffer
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 1/7] net: Add " Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 3/7] netfilter: " Stanislav Fomichev
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set. skb_dstref_steal is added to reset
existing entry without doing refcnt. Switch to skb_dstref_steal
in __xfrm_route_forward and add a comment on why it's safe
to skip skb_dstref_restore.
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
net/xfrm/xfrm_policy.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index c5035a9bc3bb..7111184eef59 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3881,12 +3881,18 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
}
skb_dst_force(skb);
- if (!skb_dst(skb)) {
+ dst = skb_dst(skb);
+ if (!dst) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR);
return 0;
}
- dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE);
+ /* ignore return value from skb_dstref_steal, xfrm_lookup takes
+ * care of dropping the refcnt if needed.
+ */
+ skb_dstref_steal(skb);
+
+ dst = xfrm_lookup(net, dst, &fl, NULL, XFRM_LOOKUP_QUEUE);
if (IS_ERR(dst)) {
res = 0;
dst = NULL;
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 3/7] netfilter: Switch to skb_dstref_steal to clear dst_entry
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 1/7] net: Add " Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers Stanislav Fomichev
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set. skb_dstref_steal is added to reset
existing entry without doing refcnt. Switch to skb_dstref_steal
in ip[6]_route_me_harder and add a comment on why it's safe
to skip skb_dstref_restore.
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
net/ipv4/netfilter.c | 5 ++++-
net/ipv6/netfilter.c | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 0565f001120d..e60e54e7945d 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -65,7 +65,10 @@ int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, un
if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
xfrm_decode_session(net, skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
struct dst_entry *dst = skb_dst(skb);
- skb_dst_set(skb, NULL);
+ /* ignore return value from skb_dstref_steal, xfrm_lookup takes
+ * care of dropping the refcnt if needed.
+ */
+ skb_dstref_steal(skb);
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), sk, 0);
if (IS_ERR(dst))
return PTR_ERR(dst);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 45f9105f9ac1..46540a5a4331 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -63,7 +63,10 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
xfrm_decode_session(net, skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
- skb_dst_set(skb, NULL);
+ /* ignore return value from skb_dstref_steal, xfrm_lookup takes
+ * care of dropping the refcnt if needed.
+ */
+ skb_dstref_steal(skb);
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
if (IS_ERR(dst))
return PTR_ERR(dst);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (2 preceding siblings ...)
2025-08-18 15:40 ` [PATCH net-next v2 3/7] netfilter: " Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop Stanislav Fomichev
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set. skb_dstref_steal is added to reset
existing entry without doing refcnt. skb_dstref_restore should
be used to restore the previous entry. Convert icmp_route_lookup
and ip_options_rcv_srr to these helpers. Add extra call to
skb_dstref_reset to icmp_route_lookup to clear the ip_route_input
entry.
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
net/ipv4/icmp.c | 7 ++++---
net/ipv4/ip_options.c | 5 ++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 2ffe73ea644f..91765057aa1d 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -544,14 +544,15 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
goto relookup_failed;
}
/* Ugh! */
- orefdst = skb_in->_skb_refdst; /* save old refdst */
- skb_dst_set(skb_in, NULL);
+ orefdst = skb_dstref_steal(skb_in);
err = ip_route_input(skb_in, fl4_dec.daddr, fl4_dec.saddr,
dscp, rt2->dst.dev) ? -EINVAL : 0;
dst_release(&rt2->dst);
rt2 = skb_rtable(skb_in);
- skb_in->_skb_refdst = orefdst; /* restore old refdst */
+ /* steal dst entry from skb_in, don't drop refcnt */
+ skb_dstref_steal(skb_in);
+ skb_dstref_restore(skb_in, orefdst);
}
if (err)
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index e3321932bec0..be8815ce3ac2 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -615,14 +615,13 @@ int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev)
}
memcpy(&nexthop, &optptr[srrptr-1], 4);
- orefdst = skb->_skb_refdst;
- skb_dst_set(skb, NULL);
+ orefdst = skb_dstref_steal(skb);
err = ip_route_input(skb, nexthop, iph->saddr, ip4h_dscp(iph),
dev) ? -EINVAL : 0;
rt2 = skb_rtable(skb);
if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
skb_dst_drop(skb);
- skb->_skb_refdst = orefdst;
+ skb_dstref_restore(skb, orefdst);
return -EINVAL;
}
refdst_drop(orefdst);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (3 preceding siblings ...)
2025-08-18 15:40 ` [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset Stanislav Fomichev
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Instead of doing dst_release and skb_dst_set, do skb_dst_drop which
should do the right thing.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
drivers/staging/octeon/ethernet-tx.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
index 261f8dbdc382..0ba240e634a1 100644
--- a/drivers/staging/octeon/ethernet-tx.c
+++ b/drivers/staging/octeon/ethernet-tx.c
@@ -346,8 +346,7 @@ netdev_tx_t cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
* The skbuff will be reused without ever being freed. We must
* cleanup a bunch of core things.
*/
- dst_release(skb_dst(skb));
- skb_dst_set(skb, NULL);
+ skb_dst_drop(skb);
skb_ext_reset(skb);
nf_reset_ct(skb);
skb_reset_redirect(skb);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (4 preceding siblings ...)
2025-08-18 15:40 ` [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 7/7] net: Add skb_dst_check_unset Stanislav Fomichev
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set. skb_dstref_steal is added to reset
existing entry without doing refcnt. Chelsio driver is
doing extra dst management via skb_dst_set(NULL). Replace
these calls with skb_dstref_steal.
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
.../ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 10 +++++-----
.../ethernet/chelsio/inline_crypto/chtls/chtls_cm.h | 4 ++--
.../ethernet/chelsio/inline_crypto/chtls/chtls_io.c | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
index 6f6525983130..2e7c2691a193 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
@@ -171,7 +171,7 @@ static void chtls_purge_receive_queue(struct sock *sk)
struct sk_buff *skb;
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
- skb_dst_set(skb, (void *)NULL);
+ skb_dstref_steal(skb);
kfree_skb(skb);
}
}
@@ -194,7 +194,7 @@ static void chtls_purge_recv_queue(struct sock *sk)
struct sk_buff *skb;
while ((skb = __skb_dequeue(&tlsk->sk_recv_queue)) != NULL) {
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
kfree_skb(skb);
}
}
@@ -1734,7 +1734,7 @@ static int chtls_rx_data(struct chtls_dev *cdev, struct sk_buff *skb)
pr_err("can't find conn. for hwtid %u.\n", hwtid);
return -EINVAL;
}
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
process_cpl_msg(chtls_recv_data, sk, skb);
return 0;
}
@@ -1786,7 +1786,7 @@ static int chtls_rx_pdu(struct chtls_dev *cdev, struct sk_buff *skb)
pr_err("can't find conn. for hwtid %u.\n", hwtid);
return -EINVAL;
}
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
process_cpl_msg(chtls_recv_pdu, sk, skb);
return 0;
}
@@ -1855,7 +1855,7 @@ static int chtls_rx_cmp(struct chtls_dev *cdev, struct sk_buff *skb)
pr_err("can't find conn. for hwtid %u.\n", hwtid);
return -EINVAL;
}
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
process_cpl_msg(chtls_rx_hdr, sk, skb);
return 0;
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h
index f61ca657601c..2285cf2df251 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h
+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h
@@ -171,14 +171,14 @@ static inline void chtls_set_req_addr(struct request_sock *oreq,
static inline void chtls_free_skb(struct sock *sk, struct sk_buff *skb)
{
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
__skb_unlink(skb, &sk->sk_receive_queue);
__kfree_skb(skb);
}
static inline void chtls_kfree_skb(struct sock *sk, struct sk_buff *skb)
{
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
__skb_unlink(skb, &sk->sk_receive_queue);
kfree_skb(skb);
}
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c
index 465fa8077964..4036db466e18 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c
@@ -1434,7 +1434,7 @@ static int chtls_pt_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
continue;
found_ok_skb:
if (!skb->len) {
- skb_dst_set(skb, NULL);
+ skb_dstref_steal(skb);
__skb_unlink(skb, &sk->sk_receive_queue);
kfree_skb(skb);
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v2 7/7] net: Add skb_dst_check_unset
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (5 preceding siblings ...)
2025-08-18 15:40 ` [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset Stanislav Fomichev
@ 2025-08-18 15:40 ` Stanislav Fomichev
2025-08-19 15:41 ` [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore syzbot ci
2025-08-20 3:11 ` [PATCH net-next v2 0/7] " patchwork-bot+netdevbpf
8 siblings, 0 replies; 13+ messages in thread
From: Stanislav Fomichev @ 2025-08-18 15:40 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev, gregkh,
horms, dsahern, pablo, kadlec, fw, steffen.klassert, sdf, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
To prevent dst_entry leaks, add warning when the non-NULL dst_entry
is rewritten.
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
---
include/linux/skbuff.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 7538ca507ee9..ca8be45dd8be 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1159,6 +1159,12 @@ static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
return (struct dst_entry *)(skb->_skb_refdst & SKB_DST_PTRMASK);
}
+static inline void skb_dst_check_unset(struct sk_buff *skb)
+{
+ DEBUG_NET_WARN_ON_ONCE((skb->_skb_refdst & SKB_DST_PTRMASK) &&
+ !(skb->_skb_refdst & SKB_DST_NOREF));
+}
+
/**
* skb_dstref_steal() - return current dst_entry value and clear it
* @skb: buffer
@@ -1188,6 +1194,7 @@ static inline unsigned long skb_dstref_steal(struct sk_buff *skb)
*/
static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
{
+ skb_dst_check_unset(skb);
skb->_skb_refdst = refdst;
}
@@ -1201,6 +1208,7 @@ static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst)
*/
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
{
+ skb_dst_check_unset(skb);
skb->slow_gro |= !!dst;
skb->_skb_refdst = (unsigned long)dst;
}
@@ -1217,6 +1225,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
*/
static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst)
{
+ skb_dst_check_unset(skb);
WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held());
skb->slow_gro |= !!dst;
skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF;
--
2.50.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (6 preceding siblings ...)
2025-08-18 15:40 ` [PATCH net-next v2 7/7] net: Add skb_dst_check_unset Stanislav Fomichev
@ 2025-08-19 15:41 ` syzbot ci
2025-08-20 0:58 ` Jakub Kicinski
2025-08-20 3:11 ` [PATCH net-next v2 0/7] " patchwork-bot+netdevbpf
8 siblings, 1 reply; 13+ messages in thread
From: syzbot ci @ 2025-08-19 15:41 UTC (permalink / raw)
To: abhishektamboli9, andrew, ayush.sawal, coreteam, davem, dsahern,
edumazet, fw, gregkh, herbert, horms, kadlec, kuba, linux-kernel,
linux-staging, mhal, netdev, netfilter-devel, pabeni, pablo, sdf,
steffen.klassert
Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v2] net: Convert to skb_dstref_steal and skb_dstref_restore
https://lore.kernel.org/all/20250818154032.3173645-1-sdf@fomichev.me
* [PATCH net-next v2 1/7] net: Add skb_dstref_steal and skb_dstref_restore
* [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry
* [PATCH net-next v2 3/7] netfilter: Switch to skb_dstref_steal to clear dst_entry
* [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
* [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop
* [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset
* [PATCH net-next v2 7/7] net: Add skb_dst_check_unset
and found the following issue:
WARNING in nf_reject_fill_skb_dst
Full report is available here:
https://ci.syzbot.org/series/74fec874-bca1-42a5-bb58-f3f49b95e348
***
WARNING in nf_reject_fill_skb_dst
tree: net-next
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net-next.git
base: 8159572936392b514e404bab2d60e47cebd5acfe
arch: amd64
compiler: Debian clang version 20.1.7 (++20250616065708+6146a88f6049-1~exp1~20250616065826.132), Debian LLD 20.1.7
config: https://ci.syzbot.org/builds/10161afb-c9c1-4272-851c-1ded15995879/config
C repro: https://ci.syzbot.org/findings/7f681f6a-9952-49a0-8533-0bc185291f81/c_repro
syz repro: https://ci.syzbot.org/findings/7f681f6a-9952-49a0-8533-0bc185291f81/syz_repro
------------[ cut here ]------------
WARNING: CPU: 1 PID: 5862 at ./include/linux/skbuff.h:1165 skb_dst_check_unset include/linux/skbuff.h:1164 [inline]
WARNING: CPU: 1 PID: 5862 at ./include/linux/skbuff.h:1165 skb_dst_set include/linux/skbuff.h:1211 [inline]
WARNING: CPU: 1 PID: 5862 at ./include/linux/skbuff.h:1165 nf_reject_fill_skb_dst+0x2a4/0x330 net/ipv4/netfilter/nf_reject_ipv4.c:234
Modules linked in:
CPU: 1 UID: 0 PID: 5862 Comm: kworker/u8:2 Not tainted 6.17.0-rc1-syzkaller-00207-g815957293639-dirty #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Workqueue: ipv6_addrconf addrconf_dad_work
RIP: 0010:skb_dst_check_unset include/linux/skbuff.h:1164 [inline]
RIP: 0010:skb_dst_set include/linux/skbuff.h:1211 [inline]
RIP: 0010:nf_reject_fill_skb_dst+0x2a4/0x330 net/ipv4/netfilter/nf_reject_ipv4.c:234
Code: 8b 0d 60 75 8b 08 48 3b 8c 24 e0 00 00 00 75 5d 48 8d 65 d8 5b 41 5c 41 5d 41 5e 41 5f 5d e9 03 91 67 01 cc e8 ad d0 aa f7 90 <0f> 0b 90 e9 38 ff ff ff 44 89 f9 80 e1 07 fe c1 38 c1 0f 8c 2b fe
RSP: 0018:ffffc900001e0360 EFLAGS: 00010246
RAX: ffffffff8a14dae3 RBX: ffff88810f943b00 RCX: ffff888109618000
RDX: 0000000000000100 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffffc900001e0490 R08: ffffffff8fa37e37 R09: 1ffffffff1f46fc6
R10: dffffc0000000000 R11: fffffbfff1f46fc7 R12: ffff88810ec56101
R13: dffffc0000000001 R14: 1ffff9200003c070 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff8881a3c1b000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000002f6a520 CR3: 0000000027716000 CR4: 00000000000006f0
Call Trace:
<IRQ>
nf_send_unreach+0x17b/0x6e0 net/ipv4/netfilter/nf_reject_ipv4.c:325
nft_reject_inet_eval+0x4bc/0x690 net/netfilter/nft_reject_inet.c:27
expr_call_ops_eval net/netfilter/nf_tables_core.c:237 [inline]
nft_do_chain+0x40c/0x1920 net/netfilter/nf_tables_core.c:285
nft_do_chain_inet+0x25d/0x340 net/netfilter/nft_chain_filter.c:161
nf_hook_entry_hookfn include/linux/netfilter.h:158 [inline]
nf_hook_slow+0xc5/0x220 net/netfilter/core.c:623
nf_hook include/linux/netfilter.h:273 [inline]
NF_HOOK+0x206/0x3a0 include/linux/netfilter.h:316
__netif_receive_skb_one_core net/core/dev.c:5979 [inline]
__netif_receive_skb+0x143/0x380 net/core/dev.c:6092
process_backlog+0x60e/0x14f0 net/core/dev.c:6444
__napi_poll+0xc7/0x360 net/core/dev.c:7494
napi_poll net/core/dev.c:7557 [inline]
net_rx_action+0x707/0xe30 net/core/dev.c:7684
handle_softirqs+0x286/0x870 kernel/softirq.c:579
do_softirq+0xec/0x180 kernel/softirq.c:480
</IRQ>
<TASK>
__local_bh_enable_ip+0x17d/0x1c0 kernel/softirq.c:407
local_bh_enable include/linux/bottom_half.h:33 [inline]
rcu_read_unlock_bh include/linux/rcupdate.h:910 [inline]
__dev_queue_xmit+0x1d79/0x3b50 net/core/dev.c:4740
neigh_output include/net/neighbour.h:547 [inline]
ip6_finish_output2+0x11fe/0x16a0 net/ipv6/ip6_output.c:141
NF_HOOK include/linux/netfilter.h:318 [inline]
ndisc_send_skb+0xb96/0x1470 net/ipv6/ndisc.c:512
ndisc_send_ns+0xcb/0x150 net/ipv6/ndisc.c:670
addrconf_dad_work+0xaae/0x14b0 net/ipv6/addrconf.c:4282
process_one_work kernel/workqueue.c:3236 [inline]
process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3319
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
kthread+0x711/0x8a0 kernel/kthread.c:463
ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore
2025-08-19 15:41 ` [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore syzbot ci
@ 2025-08-20 0:58 ` Jakub Kicinski
2025-08-20 10:45 ` Aleksandr Nogikh
0 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2025-08-20 0:58 UTC (permalink / raw)
To: Aleksandr Nogikh
Cc: syzbot ci, abhishektamboli9, andrew, ayush.sawal, coreteam, davem,
dsahern, edumazet, fw, gregkh, herbert, horms, kadlec,
linux-kernel, linux-staging, mhal, netdev, netfilter-devel,
pabeni, pablo, sdf, steffen.klassert, syzbot, syzkaller-bugs
On Tue, 19 Aug 2025 08:41:36 -0700 syzbot ci wrote:
> syzbot ci has tested the following series
>
> [v2] net: Convert to skb_dstref_steal and skb_dstref_restore
> https://lore.kernel.org/all/20250818154032.3173645-1-sdf@fomichev.me
> * [PATCH net-next v2 1/7] net: Add skb_dstref_steal and skb_dstref_restore
> * [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry
> * [PATCH net-next v2 3/7] netfilter: Switch to skb_dstref_steal to clear dst_entry
> * [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
> * [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop
> * [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset
> * [PATCH net-next v2 7/7] net: Add skb_dst_check_unset
> ***
>
> If these findings have caused you to resend the series or submit a
> separate fix, please add the following tag to your commit message:
> Tested-by: syzbot@syzkaller.appspotmail.com
Hi Aleksandr!
Could we do something about this Tested-by: tag?
Since the syzbot CI reports are sent in reply to a series patchwork and
other tooling will think that syzbot is sending it's Tested-by tag for
this series.
In some cases we know that the issues found are unrelated, or rather
expect them to be fixed separately.
Could we perhaps indent the tag with a couple of spaces? Not 100% sure
but I _think_ most tools will match the tags only from start of line.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
` (7 preceding siblings ...)
2025-08-19 15:41 ` [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore syzbot ci
@ 2025-08-20 3:11 ` patchwork-bot+netdevbpf
8 siblings, 0 replies; 13+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-08-20 3:11 UTC (permalink / raw)
To: Stanislav Fomichev
Cc: netdev, davem, edumazet, kuba, pabeni, ayush.sawal, andrew+netdev,
gregkh, horms, dsahern, pablo, kadlec, fw, steffen.klassert, mhal,
abhishektamboli9, linux-kernel, linux-staging, netfilter-devel,
coreteam, herbert
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 18 Aug 2025 08:40:25 -0700 you wrote:
> To diagnose and prevent issues similar to [0], emit warning
> (CONFIG_DEBUG_NET) from skb_dst_set and skb_dst_set_noref when
> overwriting non-null reference-counted entry. Two new helpers
> are added to handle special cases where the entry needs to be
> reset and restored: skb_dstref_steal/skb_dstref_restore. The bulk of
> the patches in the series converts manual _skb_refst manipulations
> to these new helpers.
>
> [...]
Here is the summary with links:
- [net-next,v2,1/7] net: Add skb_dstref_steal and skb_dstref_restore
https://git.kernel.org/netdev/net-next/c/c3f0c02997c7
- [net-next,v2,2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry
https://git.kernel.org/netdev/net-next/c/c829aab21ed5
- [net-next,v2,3/7] netfilter: Switch to skb_dstref_steal to clear dst_entry
https://git.kernel.org/netdev/net-next/c/15488d4d8dc1
- [net-next,v2,4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
https://git.kernel.org/netdev/net-next/c/e97e6a1830dd
- [net-next,v2,5/7] staging: octeon: Convert to skb_dst_drop
https://git.kernel.org/netdev/net-next/c/da3b9d493ba2
- [net-next,v2,6/7] chtls: Convert to skb_dst_reset
https://git.kernel.org/netdev/net-next/c/3e31075a1194
- [net-next,v2,7/7] net: Add skb_dst_check_unset
https://git.kernel.org/netdev/net-next/c/a890348adcc9
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore
2025-08-20 0:58 ` Jakub Kicinski
@ 2025-08-20 10:45 ` Aleksandr Nogikh
2025-08-20 15:08 ` Jakub Kicinski
0 siblings, 1 reply; 13+ messages in thread
From: Aleksandr Nogikh @ 2025-08-20 10:45 UTC (permalink / raw)
To: Jakub Kicinski
Cc: syzbot ci, abhishektamboli9, andrew, ayush.sawal, coreteam, davem,
dsahern, edumazet, fw, gregkh, herbert, horms, kadlec,
linux-kernel, linux-staging, mhal, netdev, netfilter-devel,
pabeni, pablo, sdf, steffen.klassert, syzbot, syzkaller-bugs
Hi Jakub,
Thanks for the heads-up!
I didn't even think that this tag could pose problems for other
automatic tools :)
On Wed, Aug 20, 2025 at 2:58 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Tue, 19 Aug 2025 08:41:36 -0700 syzbot ci wrote:
> > syzbot ci has tested the following series
> >
> > [v2] net: Convert to skb_dstref_steal and skb_dstref_restore
> > https://lore.kernel.org/all/20250818154032.3173645-1-sdf@fomichev.me
> > * [PATCH net-next v2 1/7] net: Add skb_dstref_steal and skb_dstref_restore
> > * [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry
> > * [PATCH net-next v2 3/7] netfilter: Switch to skb_dstref_steal to clear dst_entry
> > * [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers
> > * [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop
> > * [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset
> > * [PATCH net-next v2 7/7] net: Add skb_dst_check_unset
>
> > ***
> >
> > If these findings have caused you to resend the series or submit a
> > separate fix, please add the following tag to your commit message:
> > Tested-by: syzbot@syzkaller.appspotmail.com
>
> Hi Aleksandr!
>
> Could we do something about this Tested-by: tag?
> Since the syzbot CI reports are sent in reply to a series patchwork and
> other tooling will think that syzbot is sending it's Tested-by tag for
> this series.
>
> In some cases we know that the issues found are unrelated, or rather
> expect them to be fixed separately.
FWIW if you notice the reported issues that are completely unrelated,
please let me know.
>
> Could we perhaps indent the tag with a couple of spaces? Not 100% sure
> but I _think_ most tools will match the tags only from start of line.
Sure, that sounds like a very simple solution.
I've adjusted the email template - now there are several leading
whitespaces on the tag line. I hope it will help (otherwise we'll see
what else can be done).
--
Aleksandr
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore
2025-08-20 10:45 ` Aleksandr Nogikh
@ 2025-08-20 15:08 ` Jakub Kicinski
0 siblings, 0 replies; 13+ messages in thread
From: Jakub Kicinski @ 2025-08-20 15:08 UTC (permalink / raw)
To: Aleksandr Nogikh
Cc: syzbot ci, abhishektamboli9, andrew, ayush.sawal, coreteam, davem,
dsahern, edumazet, fw, gregkh, herbert, horms, kadlec,
linux-kernel, linux-staging, mhal, netdev, netfilter-devel,
pabeni, pablo, sdf, steffen.klassert, syzbot, syzkaller-bugs
On Wed, 20 Aug 2025 12:45:52 +0200 Aleksandr Nogikh wrote:
> > Could we do something about this Tested-by: tag?
> > Since the syzbot CI reports are sent in reply to a series patchwork and
> > other tooling will think that syzbot is sending it's Tested-by tag for
> > this series.
> >
> > In some cases we know that the issues found are unrelated, or rather
> > expect them to be fixed separately.
>
> FWIW if you notice the reported issues that are completely unrelated,
> please let me know.
>
> > Could we perhaps indent the tag with a couple of spaces? Not 100% sure
> > but I _think_ most tools will match the tags only from start of line.
>
> Sure, that sounds like a very simple solution.
> I've adjusted the email template - now there are several leading
> whitespaces on the tag line. I hope it will help (otherwise we'll see
> what else can be done).
Looks like we have received a report with your adjustment in place for:
https://lore.kernel.org/all/20250820092925.2115372-1-jackzxcui1989@163.com/
I can confirm that it fixes the tag propagation for our tooling.
Thank you!
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-08-20 15:08 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-18 15:40 [PATCH net-next v2 0/7] net: Convert to skb_dstref_steal and skb_dstref_restore Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 1/7] net: Add " Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 2/7] xfrm: Switch to skb_dstref_steal to clear dst_entry Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 3/7] netfilter: " Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 4/7] net: Switch to skb_dstref_steal/skb_dstref_restore for ip_route_input callers Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 5/7] staging: octeon: Convert to skb_dst_drop Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 6/7] chtls: Convert to skb_dst_reset Stanislav Fomichev
2025-08-18 15:40 ` [PATCH net-next v2 7/7] net: Add skb_dst_check_unset Stanislav Fomichev
2025-08-19 15:41 ` [syzbot ci] Re: net: Convert to skb_dstref_steal and skb_dstref_restore syzbot ci
2025-08-20 0:58 ` Jakub Kicinski
2025-08-20 10:45 ` Aleksandr Nogikh
2025-08-20 15:08 ` Jakub Kicinski
2025-08-20 3:11 ` [PATCH net-next v2 0/7] " patchwork-bot+netdevbpf
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).