[PATCH nf-next] netfilter: nf_tables: call skb_valid_dst() before skb_dst()
Pablo Neira Ayuso <[email protected]> Tue, 28 Jul 2026 10:40:06 +0200
| Newsgroups | gmane.comp.security.firewalls.netfilter.devel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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 = ®s->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