@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netlink.h>
+#include <linux/user_namespace.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
@@ -37,6 +38,9 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,
struct nft_dup_ipv4 *priv = nft_expr_priv(expr);
int err;
+ if (ctx->net->user_ns != &init_user_ns)
+ return -EPERM;
+
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
return -EINVAL;
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netlink.h>
+#include <linux/user_namespace.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
@@ -35,6 +36,9 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,
struct nft_dup_ipv6 *priv = nft_expr_priv(expr);
int err;
+ if (ctx->net->user_ns != &init_user_ns)
+ return -EPERM;
+
if (tb[NFTA_DUP_SREG_ADDR] == NULL)
return -EINVAL;
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netlink.h>
+#include <linux/user_namespace.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
@@ -37,6 +38,9 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,
{
struct nft_dup_netdev *priv = nft_expr_priv(expr);
+ if (ctx->net->user_ns != &init_user_ns)
+ return -EPERM;
+
if (tb[NFTA_DUP_SREG_DEV] == NULL)
return -EINVAL;
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/route.h>
+#include <linux/user_namespace.h>
#include <linux/netfilter/x_tables.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -95,6 +96,9 @@ static int tee_tg_check(const struct xt_tgchk_param *par)
struct xt_tee_tginfo *info = par->targinfo;
struct xt_tee_priv *priv;
+ if (par->net->user_ns != &init_user_ns)
+ return -EPERM;
+
/* 0.0.0.0 and :: not allowed */
if (memcmp(&info->gw, &tee_zero_address,
sizeof(tee_zero_address)) == 0)
The packet-duplication frontends can permit repeated packet duplication and resource consumption when configured in a network namespace owned by a non-initial user namespace. Users with CAP_NET_ADMIN in that namespace can configure the affected rules. No use case for TEE or nft dup in such namespaces has been identified. Reject TEE and IPv4/IPv6/netdev nft dup rule or expression setup with -EPERM there, without adding checks to packet-processing fast paths. This is a namespace policy restriction, not a general fix for asynchronous duplication behavior. Rules remain installable in init_user_ns-owned network namespaces, and their existing packet-processing behavior is unchanged. Fixes: cd58bcd9787e ("netfilter: xt_TEE: have cloned packet travel through Xtables too") Fixes: 502061f81d3e ("netfilter: nf_tables: add packet duplication to the netdev family") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Assisted-by: LLM Co-developed-by: Luxing Yin <root@tr0jan.top> Signed-off-by: Luxing Yin <root@tr0jan.top> Signed-off-by: Zihan Xi <zihanx@nebusec.ai> --- changes in v5: - describe the patch as a non-initial-userns setup restriction, not a general recursion fix; state that init_user_ns behavior is unchanged - remove path-specific trigger details and run-specific metrics from the public commit and cover prose - drop d877f07112f1 from Fixes: because it added a later frontend, not the shared duplication behavior addressed by this restriction - record the v5 build and setup-time validation, distinguishing them from earlier unpatched-baseline and root-OOM runs - v4 Link: https://lore.kernel.org/all/cover.1790408011.git.zihanx@nebusec.ai/ changes in v4: - add Fixes tags for TEE, IPv4/IPv6 nft dup, and netdev nft dup frontends - clarify that fcd53c51d037 only added a synchronous guard - clarify that this restricts non-initial user namespaces and does not fix asynchronous recursion in init_user_ns-owned network namespaces - state explicitly that the netdev loop was not runtime-reproduced - v3 Link: https://lore.kernel.org/all/cover.1790042930.git.zihanx@nebusec.ai/ changes in v3: - reroll the fix against the latest nf.git main after no follow-up on v2 - add the Co-developed-by trailer and matching Signed-off-by - v2 Link: https://lore.kernel.org/all/cover.1788425393.git.zihanx@nebusec.ai/ changes in v2: - drop the persistent struct sk_buff::nf_duplicated field and nf_copy() change from v1 - disable IPv4/IPv6 duplication in non-initial user namespaces - v1 Link: https://lore.kernel.org/all/cover.1787903722.git.zihanx@nebusec.ai/ --- net/ipv4/netfilter/nft_dup_ipv4.c | 4 ++++ net/ipv6/netfilter/nft_dup_ipv6.c | 4 ++++ net/netfilter/nft_dup_netdev.c | 4 ++++ net/netfilter/xt_TEE.c | 4 ++++ 4 files changed, 16 insertions(+)