From: Florian Westphal Date: Mon, 15 Jun 2026 18:10:44 +0000 (+0200) Subject: netfilter: nft_compat: ebtables emulation must reject non-bridge targets X-Git-Tag: v7.2-rc1~29^2~14^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9dbba7e694ec045f21ede2f892fb42b81b4e1692;p=thirdparty%2Flinux.git netfilter: nft_compat: ebtables emulation must reject non-bridge targets xtables targets return netfilter verdicts: NF_ACCEPT, NF_DROP, and so on. ebtables targets return incompatible verdicts: EBT_ACCEPT, EBT_DROP, ... We cannot allow fallback to NFPROTO_UNSPEC. ebtables doesn't permit this since 11ff7288beb2 ("netfilter: ebtables: reject non-bridge targets") but that commit missed the nft_compat layer. Reported-by: Ren Wei Reported-by: Wyatt Feng Reported-by: Yuan Tan Reported-by: Yifan Wu Reported-by: Juefei Pu Reported-by: Zhengchuan Liang Reported-by: Xin Liu Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables") Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 0caa9304d2d03..63864b9282590 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -397,6 +397,22 @@ static int nft_target_validate(const struct nft_ctx *ctx, return 0; } +static int nft_target_bridge_validate(const struct nft_ctx *ctx, + const struct nft_expr *expr) +{ + struct xt_target *target = expr->ops->data; + + /* Do not allow UNSPEC to stand-in for NFPROTO_BRIDGE + * targets: they are incompatible. ebtables targets return + * EBT_ACCEPT, DROP and so on which are not compatible with + * NF_ACCEPT, NF_DROP and so on. + */ + if (target->family != NFPROTO_BRIDGE) + return -ENOENT; + + return nft_target_validate(ctx, expr); +} + static void __nft_match_eval(const struct nft_expr *expr, struct nft_regs *regs, const struct nft_pktinfo *pkt, @@ -932,13 +948,15 @@ nft_target_select_ops(const struct nft_ctx *ctx, ops->init = nft_target_init; ops->destroy = nft_target_destroy; ops->dump = nft_target_dump; - ops->validate = nft_target_validate; ops->data = target; - if (family == NFPROTO_BRIDGE) + if (family == NFPROTO_BRIDGE) { ops->eval = nft_target_eval_bridge; - else + ops->validate = nft_target_bridge_validate; + } else { ops->eval = nft_target_eval_xt; + ops->validate = nft_target_validate; + } return ops; err: