]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
netfilter: nft_compat: ebtables emulation must reject non-bridge targets
authorFlorian Westphal <fw@strlen.de>
Mon, 15 Jun 2026 18:10:44 +0000 (20:10 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 23 Jun 2026 06:11:22 +0000 (08:11 +0200)
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 <n05ec@lzu.edu.cn>
Reported-by: Wyatt Feng <bronzed_45_vested@icloud.com>
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nft_compat.c

index 0caa9304d2d0305f1cce0af8c39be91049489280..63864b9282590981cc4b1d372489d05006af7c59 100644 (file)
@@ -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: