All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst()
@ 2026-07-28  8:40 Pablo Neira Ayuso
  2026-07-29  9:33 ` Fernando Fernandez Mancera
  0 siblings, 1 reply; 3+ messages in thread
From: Pablo Neira Ayuso @ 2026-07-28  8:40 UTC (permalink / raw)
  To: netfilter-devel

When fetching the dst_entry from the skb, check if it valid, ie. this is
not a template dst.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nft_meta.c | 6 ++++--
 net/netfilter/nft_rt.c   | 6 ++++--
 net/netfilter/nft_xfrm.c | 9 ++++++++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 0a43e0787a68..01cfbaa36525 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -20,6 +20,7 @@
 #include <net/dst.h>
 #include <net/ip.h>
 #include <net/sock.h>
+#include <net/dst_metadata.h>
 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
@@ -279,11 +280,12 @@ static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
 static noinline bool
 nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
 {
-	const struct dst_entry *dst = skb_dst(skb);
+	const struct dst_entry *dst;
 
-	if (!dst)
+	if (!skb_valid_dst(skb))
 		return false;
 
+	dst = skb_dst(skb);
 	*dest = dst->tclassid;
 	return true;
 }
diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c
index aeb0094eafd8..841c863a08db 100644
--- a/net/netfilter/nft_rt.c
+++ b/net/netfilter/nft_rt.c
@@ -8,6 +8,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
 #include <net/dst.h>
+#include <net/dst_metadata.h>
 #include <net/ip6_route.h>
 #include <net/route.h>
 #include <net/netfilter/nf_tables.h>
@@ -59,10 +60,11 @@ void nft_rt_get_eval(const struct nft_expr *expr,
 	u32 *dest = &regs->data[priv->dreg];
 	const struct dst_entry *dst;
 
-	dst = skb_dst(skb);
-	if (!dst)
+	if (!skb_valid_dst(skb))
 		goto err;
 
+	dst = skb_dst(skb);
+
 	switch (priv->key) {
 #ifdef CONFIG_IP_ROUTE_CLASSID
 	case NFT_RT_CLASSID:
diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
index 8cec43064319..c8bba697f993 100644
--- a/net/netfilter/nft_xfrm.c
+++ b/net/netfilter/nft_xfrm.c
@@ -12,6 +12,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
+#include <net/dst_metadata.h>
 #include <linux/in.h>
 #include <net/xfrm.h>
 
@@ -177,9 +178,15 @@ static void nft_xfrm_get_eval_out(const struct nft_xfrm *priv,
 				  struct nft_regs *regs,
 				  const struct nft_pktinfo *pkt)
 {
-	const struct dst_entry *dst = skb_dst(pkt->skb);
+	const struct dst_entry *dst;
 	int i;
 
+	if (!skb_valid_dst(pkt->skb)) {
+		regs->verdict.code = NFT_BREAK;
+		return;
+	}
+
+	dst = skb_dst(pkt->skb);
 	for (i = 0; dst && dst->xfrm;
 	     dst = ((const struct xfrm_dst *)dst)->child, i++) {
 		if (i < priv->spnum)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst()
  2026-07-28  8:40 [PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst() Pablo Neira Ayuso
@ 2026-07-29  9:33 ` Fernando Fernandez Mancera
  2026-07-29  9:45   ` Pablo Neira Ayuso
  0 siblings, 1 reply; 3+ messages in thread
From: Fernando Fernandez Mancera @ 2026-07-29  9:33 UTC (permalink / raw)
  To: Pablo Neira Ayuso, netfilter-devel

On 7/28/26 10:40 AM, Pablo Neira Ayuso wrote:
> When fetching the dst_entry from the skb, check if it valid, ie. this is
> not a template dst.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Hi Pablo,

I used a coccinelle script to see if this pattern is present in other 
places. So far in Netfilter I have found this in 
net/ipv6/netfilter/nf_reject_ipv6.c:nf_send_reset6()

         if (!skb_dst(oldskb)) {
                 nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false);
                 if (!dst)
                         return;
                 skb_dst_set(oldskb, dst);
         }

If I am not wrong the same problem happens here too.

> ---
>   net/netfilter/nft_meta.c | 6 ++++--
>   net/netfilter/nft_rt.c   | 6 ++++--
>   net/netfilter/nft_xfrm.c | 9 ++++++++-
>   3 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
> index 0a43e0787a68..01cfbaa36525 100644
> --- a/net/netfilter/nft_meta.c
> +++ b/net/netfilter/nft_meta.c
> @@ -20,6 +20,7 @@
>   #include <net/dst.h>
>   #include <net/ip.h>
>   #include <net/sock.h>
> +#include <net/dst_metadata.h>
>   #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
>   #include <net/netfilter/nf_tables.h>
>   #include <net/netfilter/nf_tables_core.h>
> @@ -279,11 +280,12 @@ static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
>   static noinline bool
>   nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
>   {
> -	const struct dst_entry *dst = skb_dst(skb);
> +	const struct dst_entry *dst;
>   
> -	if (!dst)
> +	if (!skb_valid_dst(skb))
>   		return false;
>   
> +	dst = skb_dst(skb);
>   	*dest = dst->tclassid;
>   	return true;
>   }
> diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c
> index aeb0094eafd8..841c863a08db 100644
> --- a/net/netfilter/nft_rt.c
> +++ b/net/netfilter/nft_rt.c
> @@ -8,6 +8,7 @@
>   #include <linux/netfilter.h>
>   #include <linux/netfilter/nf_tables.h>
>   #include <net/dst.h>
> +#include <net/dst_metadata.h>
>   #include <net/ip6_route.h>
>   #include <net/route.h>
>   #include <net/netfilter/nf_tables.h>
> @@ -59,10 +60,11 @@ void nft_rt_get_eval(const struct nft_expr *expr,
>   	u32 *dest = &regs->data[priv->dreg];
>   	const struct dst_entry *dst;
>   
> -	dst = skb_dst(skb);
> -	if (!dst)
> +	if (!skb_valid_dst(skb))
>   		goto err;
>   
> +	dst = skb_dst(skb);
> +
>   	switch (priv->key) {
>   #ifdef CONFIG_IP_ROUTE_CLASSID
>   	case NFT_RT_CLASSID:
> diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
> index 8cec43064319..c8bba697f993 100644
> --- a/net/netfilter/nft_xfrm.c
> +++ b/net/netfilter/nft_xfrm.c
> @@ -12,6 +12,7 @@
>   #include <linux/netfilter/nf_tables.h>
>   #include <net/netfilter/nf_tables_core.h>
>   #include <net/netfilter/nf_tables.h>
> +#include <net/dst_metadata.h>
>   #include <linux/in.h>
>   #include <net/xfrm.h>
>   
> @@ -177,9 +178,15 @@ static void nft_xfrm_get_eval_out(const struct nft_xfrm *priv,
>   				  struct nft_regs *regs,
>   				  const struct nft_pktinfo *pkt)
>   {
> -	const struct dst_entry *dst = skb_dst(pkt->skb);
> +	const struct dst_entry *dst;
>   	int i;
>   
> +	if (!skb_valid_dst(pkt->skb)) {
> +		regs->verdict.code = NFT_BREAK;
> +		return;
> +	}
> +
> +	dst = skb_dst(pkt->skb);
>   	for (i = 0; dst && dst->xfrm;
>   	     dst = ((const struct xfrm_dst *)dst)->child, i++) {
>   		if (i < priv->spnum)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst()
  2026-07-29  9:33 ` Fernando Fernandez Mancera
@ 2026-07-29  9:45   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2026-07-29  9:45 UTC (permalink / raw)
  To: Fernando Fernandez Mancera; +Cc: netfilter-devel

Hi Fernando,

On Wed, Jul 29, 2026 at 11:33:24AM +0200, Fernando Fernandez Mancera wrote:
> On 7/28/26 10:40 AM, Pablo Neira Ayuso wrote:
> > When fetching the dst_entry from the skb, check if it valid, ie. this is
> > not a template dst.
> > 
> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Hi Pablo,
> 
> I used a coccinelle script to see if this pattern is present in other
> places. So far in Netfilter I have found this in
> net/ipv6/netfilter/nf_reject_ipv6.c:nf_send_reset6()
> 
>         if (!skb_dst(oldskb)) {
>                 nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false);
>                 if (!dst)
>                         return;
>                 skb_dst_set(oldskb, dst);
>         }
> 
> If I am not wrong the same problem happens here too.

Good point.

It was intentional, I thought this is never called from netdev
ingress/egress.

I can expand the commit message to explicitly mention that the
intention is to check for valid dst in the netdev/ingress,egrees paths
where the template dst can be seen.

But, after second glance, this can be indeed called from
NF_INET_INGRESS.

So this chunk is really needed, I will post v2, thanks!

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-29  9:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28  8:40 [PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst() Pablo Neira Ayuso
2026-07-29  9:33 ` Fernando Fernandez Mancera
2026-07-29  9:45   ` Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.