netfilter: nft_compat: restrict raw table targets/matches

xt targets and matches declaring .table = "raw" (CT, NOTRACK) rely on
only ever running in the legacy raw table's prerouting/output chains,
ahead of conntrack. nft_compat_chain_validate_dependency() already
enforces this kind of correspondence for "nat" by requiring the chain
type to actually be NAT, but did nothing for "raw": a rule wrapping
the CT target could be loaded into any hook and any priority via
nft_compat, including after the real conntrack hook has already run.

The CT target attaches a conntrack template to the skb when none is
set yet.

Require that a "raw" table dependency actually matches what xtables
enforces via the implict/builtin table dependency.

Fixes: 0ca743a559 ("netfilter: nf_tables: add compatibility layer for x_tables")
Assisted-by: LLM
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2026-10-07 01:15:49 +02:00 committed by Pablo Neira Ayuso
parent a20a01ae89
commit ac364eb4d6

View File

@ -14,6 +14,7 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
@ -45,6 +46,20 @@ static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
type = NFT_CHAIN_T_NAT;
if (basechain->type->type != type)
return -EINVAL;
} else if (strcmp(tablename, "raw") == 0) {
/* iptables-nft emulates the legacy raw table, which only
* ever has prerouting/output chains at this exact priority.
*/
if (ctx->family != NFPROTO_IPV4 &&
ctx->family != NFPROTO_IPV6)
return -EINVAL;
if (basechain->ops.hooknum != NF_INET_PRE_ROUTING &&
basechain->ops.hooknum != NF_INET_LOCAL_OUT)
return -EINVAL;
if (basechain->ops.priority != NF_IP_PRI_RAW)
return -EINVAL;
}
return 0;