netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
@ 2025-08-29  6:50 Nikolaos Gkarlis
  2025-08-29 15:08 ` Florian Westphal
  0 siblings, 1 reply; 13+ messages in thread
From: Nikolaos Gkarlis @ 2025-08-29  6:50 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, fw, Nikolaos Gkarlis

The kernel accepts netlink messages using the legacy NFT_CT_SRC,
NFT_CT_DST keys in inet tables, creating ambiguous conntrack expressions
that cannot be properly evaluated during packet processing.

When NFPROTO_INET is used with NFT_CT_SRC, NFT_CT_DST the register size
calculation defaults to IPv6 (16 bytes) regardless of the actual packet
family.

This causes two issues:
1. For IPv4 packets, only 4 bytes contain valid address data while 12
   bytes contain uninitialized memory during comparison.
2. nft userspace cannot properly display these rules ([invalid type]).

The bug is not reproducible through standard nft commands, which
properly use NFT_CT_SRC_IP(6), NFT_CT_DST_IP(6) keys instead.

Fix by rejecting such expressions with EAFNOSUPPORT when used in inet
tables.

Signed-off-by: Nikolaos Gkarlis <nickgarlis@gmail.com>
---
As an example, packets from 192.0.2.1 (0xc0000201) would also match
rules filtering on c000:201:: (0xc0000201000000000000000000000000),
which is likely unintended. To my knowledge, the keys NFT_CT_SRC and
NFT_CT_DST were never officially used by nft userspace, so I assume
rejecting them should be safe. I have tested this change and it appears
to work as expected.

 net/netfilter/nft_ct.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index d526e69a2..23ce90975 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -439,7 +439,6 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
 					   src.u3.ip);
 			break;
 		case NFPROTO_IPV6:
-		case NFPROTO_INET:
 			len = sizeof_field(struct nf_conntrack_tuple,
 					   src.u3.ip6);
 			break;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-08-29  6:50 [PATCH] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables Nikolaos Gkarlis
@ 2025-08-29 15:08 ` Florian Westphal
  2025-08-29 21:59   ` Nick Garlis
  0 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2025-08-29 15:08 UTC (permalink / raw)
  To: Nikolaos Gkarlis; +Cc: netfilter-devel, pablo

Nikolaos Gkarlis <nickgarlis@gmail.com> wrote:
> The kernel accepts netlink messages using the legacy NFT_CT_SRC,
> NFT_CT_DST keys in inet tables, creating ambiguous conntrack expressions
> that cannot be properly evaluated during packet processing.
> 
> When NFPROTO_INET is used with NFT_CT_SRC, NFT_CT_DST the register size
> calculation defaults to IPv6 (16 bytes) regardless of the actual packet
> family.
> 
> This causes two issues:
> 1. For IPv4 packets, only 4 bytes contain valid address data while 12
>    bytes contain uninitialized memory during comparison.
> 2. nft userspace cannot properly display these rules ([invalid type]).
> 
> The bug is not reproducible through standard nft commands, which
> properly use NFT_CT_SRC_IP(6), NFT_CT_DST_IP(6) keys instead.

It breaks nftables .py tests:

tests/py/nft-test.py
inet/rt.t: OK
inet/ct.t: ERROR: line 7: add rule inet test-inet input meta nfproto ipv4 ct original saddr 1.2.3.4: This rule should not have failed.
inet/ct.t: OK

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-08-29 15:08 ` Florian Westphal
@ 2025-08-29 21:59   ` Nick Garlis
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
  0 siblings, 1 reply; 13+ messages in thread
From: Nick Garlis @ 2025-08-29 21:59 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel, pablo

On Fri, Aug 29, 2025 at 5:08 PM Florian Westphal <fw@strlen.de> wrote:
> It breaks nftables .py tests:
>
> tests/py/nft-test.py
> inet/rt.t: OK
> inet/ct.t: ERROR: line 7: add rule inet test-inet input meta nfproto ipv4 ct original saddr 1.2.3.4: This rule should not have failed.
> inet/ct.t: OK

Apologies, I didn’t run the nftables Python tests.
Thanks for pointing me in the right direction.

It seems I mistakenly assumed that NFT_CT_SRC and NFT_CT_DST were never
used in inet tables. I’ll look into this further and try to come up with
a better approach.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-08-29 21:59   ` Nick Garlis
@ 2025-09-02 21:54     ` Nikolaos Gkarlis
  2025-09-02 22:21       ` Florian Westphal
                         ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Nikolaos Gkarlis @ 2025-09-02 21:54 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, fw, Nikolaos Gkarlis

The kernel allows netlink messages that use the legacy NFT_CT_SRC and
NFT_CT_DST keys in inet tables without an accompanying nft_meta
expression specifying NFT_META_NFPROTO. This results in ambiguous
conntrack expressions that cannot be reliably evaluated during packet
processing.

When that happens, the register size calculation defaults to IPv6 (16
bytes) regardless of the actual packet family.

This causes two issues:
1. For IPv4 packets, only 4 bytes contain valid address data while 12
   bytes contain uninitialized memory during comparison.
2. nft userspace cannot properly display these rules ([invalid type]).

The bug is not reproducible through standard nft commands, which use
NFT_CT_SRC_IP(6) and NFT_CT_DST_IP(6) keys when NFT_META_NFPROTO is
not defined.

Fix by adding a pointer to the parent nft_rule in nft_expr, allowing
iteration over preceding expressions to ensure that an nft_meta with
NFT_META_NFPROTO has been defined.

Signed-off-by: Nikolaos Gkarlis <nickgarlis@gmail.com>
---
Adding a pointer from nft_expr to nft_rule may be controversial, but
it was the only approach I could come up with that provides context
about preceding expressions when validating an expression.

I am not certain if this is the best way to handle it, but I am sending
the patch for review. Let me know if you would rather this handled
another way.

 include/net/netfilter/nf_tables.h |  2 ++
 include/net/netfilter/nft_meta.h  |  2 ++
 net/netfilter/nf_tables_api.c     | 10 +++++++---
 net/netfilter/nft_ct.c            | 21 +++++++++++++++++++++
 net/netfilter/nft_meta.c          |  3 ++-
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 891e43a01bdc..4beb3aa46fe0 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -403,10 +403,12 @@ struct nft_set_estimate {
  *	struct nft_expr - nf_tables expression
  *
  *	@ops: expression ops
+ *	@rule: rule this expression is contained in
  *	@data: expression private data
  */
 struct nft_expr {
 	const struct nft_expr_ops	*ops;
+	const struct nft_rule *rule;
 	unsigned char			data[]
 		__attribute__((aligned(__alignof__(u64))));
 };
diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h
index d602263590fe..93d987de78a6 100644
--- a/include/net/netfilter/nft_meta.h
+++ b/include/net/netfilter/nft_meta.h
@@ -51,4 +51,6 @@ void nft_meta_inner_eval(const struct nft_expr *expr,
 			 struct nft_regs *regs, const struct nft_pktinfo *pkt,
 			 struct nft_inner_tun_ctx *tun_ctx);
 
+extern const struct nft_expr_ops nft_meta_get_ops;
+
 #endif
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 58c5425d61c2..eab26b33d80e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3500,6 +3500,7 @@ int nft_expr_inner_parse(const struct nft_ctx *ctx, const struct nlattr *nla,
 }
 
 static int nf_tables_newexpr(const struct nft_ctx *ctx,
+			     const struct nft_rule *rule,
 			     const struct nft_expr_info *expr_info,
 			     struct nft_expr *expr)
 {
@@ -3507,6 +3508,7 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx,
 	int err;
 
 	expr->ops = ops;
+	expr->rule = rule;
 	if (ops->init) {
 		err = ops->init(ctx, expr, (const struct nlattr **)expr_info->tb);
 		if (err < 0)
@@ -3516,6 +3518,7 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx,
 	return 0;
 err1:
 	expr->ops = NULL;
+	expr->rule = NULL;
 	return err;
 }
 
@@ -3530,6 +3533,7 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
 }
 
 static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
+				      const struct nft_rule *rule,
 				      const struct nlattr *nla)
 {
 	struct nft_expr_info expr_info;
@@ -3550,7 +3554,7 @@ static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
 	if (expr == NULL)
 		goto err_expr_stateful;
 
-	err = nf_tables_newexpr(ctx, &expr_info, expr);
+	err = nf_tables_newexpr(ctx, rule, &expr_info, expr);
 	if (err < 0)
 		goto err_expr_new;
 
@@ -4339,7 +4343,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
 
 	expr = nft_expr_first(rule);
 	for (i = 0; i < n; i++) {
-		err = nf_tables_newexpr(&ctx, &expr_info[i], expr);
+		err = nf_tables_newexpr(&ctx, rule, &expr_info[i], expr);
 		if (err < 0) {
 			NL_SET_BAD_ATTR(extack, expr_info[i].attr);
 			goto err_release_rule;
@@ -6681,7 +6685,7 @@ struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
 	struct nft_expr *expr;
 	int err;
 
-	expr = nft_expr_init(ctx, attr);
+	expr = nft_expr_init(ctx, NULL, attr);
 	if (IS_ERR(expr))
 		return expr;
 
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index d526e69a2a2b..b18bd5705872 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -22,6 +22,7 @@
 #include <net/netfilter/nf_conntrack_timeout.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_expect.h>
+#include <net/netfilter/nft_meta.h>
 
 struct nft_ct_helper_obj  {
 	struct nf_conntrack_helper *helper4;
@@ -440,6 +441,26 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
 			break;
 		case NFPROTO_IPV6:
 		case NFPROTO_INET:
+			const struct nft_expr *curr, *last;
+			bool meta_nfproto = false;
+			if (!expr->rule)
+				return -EINVAL;
+
+			nft_rule_for_each_expr(curr, last, expr->rule) {
+				if (curr == expr)
+					break;
+
+				if (curr->ops == &nft_meta_get_ops) {
+					const struct nft_meta *meta = nft_expr_priv(curr);
+					if (meta->key == NFT_META_NFPROTO) {
+						meta_nfproto = true;
+						break;
+					}
+				}
+			}
+			if (!meta_nfproto)
+				return -EINVAL;
+
 			len = sizeof_field(struct nf_conntrack_tuple,
 					   src.u3.ip6);
 			break;
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 05cd1e6e6a2f..aa6bf05e3907 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -767,7 +767,7 @@ bool nft_meta_get_reduce(struct nft_regs_track *track,
 }
 EXPORT_SYMBOL_GPL(nft_meta_get_reduce);
 
-static const struct nft_expr_ops nft_meta_get_ops = {
+const struct nft_expr_ops nft_meta_get_ops = {
 	.type		= &nft_meta_type,
 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_meta)),
 	.eval		= nft_meta_get_eval,
@@ -777,6 +777,7 @@ static const struct nft_expr_ops nft_meta_get_ops = {
 	.validate	= nft_meta_get_validate,
 	.offload	= nft_meta_get_offload,
 };
+EXPORT_SYMBOL_GPL(nft_meta_get_ops);
 
 static bool nft_meta_set_reduce(struct nft_regs_track *track,
 				const struct nft_expr *expr)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
@ 2025-09-02 22:21       ` Florian Westphal
  2025-09-03  9:12         ` Nick Garlis
  2025-09-03 10:31       ` Pablo Neira Ayuso
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2025-09-02 22:21 UTC (permalink / raw)
  To: Nikolaos Gkarlis; +Cc: netfilter-devel, pablo

Nikolaos Gkarlis <nickgarlis@gmail.com> wrote:
> The kernel allows netlink messages that use the legacy NFT_CT_SRC and
> NFT_CT_DST keys in inet tables without an accompanying nft_meta
> expression specifying NFT_META_NFPROTO. This results in ambiguous
> conntrack expressions that cannot be reliably evaluated during packet
> processing.
> 
> When that happens, the register size calculation defaults to IPv6 (16
> bytes) regardless of the actual packet family.
> 
> This causes two issues:
> 1. For IPv4 packets, only 4 bytes contain valid address data while 12
>    bytes contain uninitialized memory during comparison.

I don't think so, they are zeroed out, see nf_ct_get_tuple();
init_conntrack copies the entire thing so I don't see how stack garbage
can be placed in struct nf_conn and thus I don't see how registers can
contains crap.  Do they?  If yes, please provide a bit more information
on how this happens (e.g. kmsan report or similar).

> 2. nft userspace cannot properly display these rules ([invalid type]).

Thats a userspace bug; userspace that makes use of NFT_CT_SRC/DST must
provide the dependency.

This is not the kernels job, the kernel only must make sure that we
can't crash or otherwise leak hidden state (e.g. kernel memory
contents).

> The bug is not reproducible through standard nft commands, which use
> NFT_CT_SRC_IP(6) and NFT_CT_DST_IP(6) keys when NFT_META_NFPROTO is
> not defined.

Thats because not all kernel releases have NFT_CT_DST_IP(6), they were
added later.  Switching userspace will break compatibility with older
kernels.  That said, this key was added in v4.17 so we could change
nftables now to always use NFT_CT_DST_IP(6) instead and avoid adding
the NFPROTO implicit dep for this case.

> Fix by adding a pointer to the parent nft_rule in nft_expr, allowing
> iteration over preceding expressions to ensure that an nft_meta with
> NFT_META_NFPROTO has been defined.

But why?  As far as I can see nothing is broken.

We don't force dependencies for other expressions either, why make
an exception here?

I'm sorry that I did not mention this earlier; in v1 i assumed intent
was to zap unused code (but its still used by nft), hence i did not
mention the above.

> Adding a pointer from nft_expr to nft_rule may be controversial, but
> it was the only approach I could come up with that provides context
> about preceding expressions when validating an expression.

We should not force this unless not doing it causes crash or
other misbehaviour, such as leaking private kernel memory content.

>  struct nft_expr {
>  	const struct nft_expr_ops	*ops;
> +	const struct nft_rule *rule;
>  	unsigned char			data[]
>  		__attribute__((aligned(__alignof__(u64))));

Ouch, sorry, I think this is a non-starter, nft_expr
should be kept as small as possible.

That said, I don't see why its necessary to add this pointer here,
it could be provided via nft_ctx for example.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 22:21       ` Florian Westphal
@ 2025-09-03  9:12         ` Nick Garlis
  2025-09-03 10:13           ` Florian Westphal
  0 siblings, 1 reply; 13+ messages in thread
From: Nick Garlis @ 2025-09-03  9:12 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel, pablo

Florian Westphal <fw@strlen.de> wrote:
> I don't think so, they are zeroed out, see nf_ct_get_tuple();
> init_conntrack copies the entire thing so I don't see how stack garbage
> can be placed in struct nf_conn and thus I don't see how registers can
> contains crap.

Yes they are zeroed out, sorry for the confusion. I haven't observed any
leaks. What I meant was that if you manage to create such rules from a
buggy userspace you get something like this:

table inet test-table {
  chain test-chain {
    type filter hook input priority filter; policy accept;
    ct original saddr 0xc0000201000000000000000000000000 [invalid
type] counter packets 0 bytes 0
    ct original saddr 0xc0000201 [invalid type] counter packets 0 bytes 0
  }
}

In my test, the first rule contains c000:201:: and the second one
192.0.2.1.

When I send test packets with:

    nping --tcp -p 80 --source-ip 192.0.2.1 127.0.0.1

I see the counters for both rules being increased suggesting that both
of them matched:

table inet test-table {
  chain test-chain {
    type filter hook input priority filter; policy accept;
    ct original saddr 0xc0000201000000000000000000000000 [invalid
type] counter packets 3 bytes 120
    ct original saddr 0xc0000201 [invalid type] counter packets 3 bytes 120
  }
}

> Thats a userspace bug; userspace that makes use of NFT_CT_SRC/DST must
> provide the dependency.

Yes I guess that makes sense, garbage in, garbage out. I was just used
to seeing some kind of errno being returned from any other invalid input
and I assumed that it might have been a bug in the validation.

> But why?  As far as I can see nothing is broken.

Honestly, I am not really sure whether it is an issue or not and this
was mostly driven by the assumption that the kernel shouldn't trust the
userspace to properly validate its input.

> We don't force dependencies for other expressions either, why make
> an exception here?

There is probably no strong enough reason to. Was the decision to not
force dependencies intentional or something that was left as a TODO?

> I'm sorry that I did not mention this earlier; in v1 i assumed intent
> was to zap unused code (but its still used by nft), hence i did not
> mention the above.

No problem, diving into this was mostly done for fun.

> Ouch, sorry, I think this is a non-starter, nft_expr
> should be kept as small as possible.

Yes, putting a pointer there was kinda silly.

Thanks for taking the time to explain. Let me know if you'd like any
more info about this or another patch involving nft_ctx instead.
Otherwise, I’m fine leaving this here.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-03  9:12         ` Nick Garlis
@ 2025-09-03 10:13           ` Florian Westphal
  2025-09-03 10:34             ` Pablo Neira Ayuso
  0 siblings, 1 reply; 13+ messages in thread
From: Florian Westphal @ 2025-09-03 10:13 UTC (permalink / raw)
  To: Nick Garlis; +Cc: netfilter-devel, pablo

Nick Garlis <nickgarlis@gmail.com> wrote:
> Florian Westphal <fw@strlen.de> wrote:
> > Thats a userspace bug; userspace that makes use of NFT_CT_SRC/DST must
> > provide the dependency.
> 
> Yes I guess that makes sense, garbage in, garbage out. I was just used
> to seeing some kind of errno being returned from any other invalid input
> and I assumed that it might have been a bug in the validation.
> 
> > But why?  As far as I can see nothing is broken.
> 
> Honestly, I am not really sure whether it is an issue or not and this
> was mostly driven by the assumption that the kernel shouldn't trust the
> userspace to properly validate its input.

Its simply not possible to validate it in kernel.

Consider e.g. 'tcp dort 80'.  nftables will insert the 'its tcp' check.

But userspace can also do
'meta l4proto { 6, 17, 132} th dport { 22, 23, 80}'.

The 'read 2 bytes from start of transport header' is the same.
So kernel cannot 'force' anything.

It will make sure that 2 bytes could be read from the given
offset.  But it can't make sure that those bytes have a particular
meaning (port for instance).

> There is probably no strong enough reason to. Was the decision to not
> force dependencies intentional or something that was left as a TODO?

Its fully intentional, see above example.

> Thanks for taking the time to explain. Let me know if you'd like any
> more info about this or another patch involving nft_ctx instead.
> Otherwise, I’m fine leaving this here.

You could submit a patch for nftables userspace to no longer
emit NFT_CT_SRC/DST, I think there is no need to support kernels < 4.17
anymore.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
  2025-09-02 22:21       ` Florian Westphal
@ 2025-09-03 10:31       ` Pablo Neira Ayuso
  2025-09-03 13:18       ` kernel test robot
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-03 10:31 UTC (permalink / raw)
  To: Nikolaos Gkarlis; +Cc: netfilter-devel, fw

On Tue, Sep 02, 2025 at 11:54:33PM +0200, Nikolaos Gkarlis wrote:
> The kernel allows netlink messages that use the legacy NFT_CT_SRC and
> NFT_CT_DST keys in inet tables without an accompanying nft_meta
> expression specifying NFT_META_NFPROTO. This results in ambiguous
> conntrack expressions that cannot be reliably evaluated during packet
> processing.
> 
> When that happens, the register size calculation defaults to IPv6 (16
> bytes) regardless of the actual packet family.
> 
> This causes two issues:
> 1. For IPv4 packets, only 4 bytes contain valid address data while 12
>    bytes contain uninitialized memory during comparison.
> 2. nft userspace cannot properly display these rules ([invalid type]).
> 
> The bug is not reproducible through standard nft commands, which use
> NFT_CT_SRC_IP(6) and NFT_CT_DST_IP(6) keys when NFT_META_NFPROTO is
> not defined.
> 
> Fix by adding a pointer to the parent nft_rule in nft_expr, allowing
> iteration over preceding expressions to ensure that an nft_meta with
> NFT_META_NFPROTO has been defined.

I think it is easier to work around this from userspace by translating
NFT_CT_SRC to NFT_CT_SRC_{IPV4,IPV6} by peeking the datatype at the
rhs of the relational.

NFT_CT_{SRC,DST} only works with relational expression, they are
broken with sets, that's why NFT_CT_SRC_{IPV4,IPV6} was introduced
(which works with both relational expressions and sets).

IIRC, I removed documentation for this syntax time ago with the
expectation, it seems someone found it and it is buggy with
NFPROTO_INET as you describe.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-03 10:13           ` Florian Westphal
@ 2025-09-03 10:34             ` Pablo Neira Ayuso
  2025-09-03 11:51               ` Nikolaos Gkarlis
  0 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-03 10:34 UTC (permalink / raw)
  To: Florian Westphal; +Cc: Nick Garlis, netfilter-devel

On Wed, Sep 03, 2025 at 12:13:38PM +0200, Florian Westphal wrote:
[...]
> You could submit a patch for nftables userspace to no longer
> emit NFT_CT_SRC/DST, I think there is no need to support kernels < 4.17
> anymore.

Yes. Better to fix this from userspace.

linux-stable-5.4$ git grep NFT_CT_DST_IP include/
include/uapi/linux/netfilter/nf_tables.h: * @NFT_CT_DST_IP: conntrack layer 3 protocol destination (IPv4 address)
include/uapi/linux/netfilter/nf_tables.h: * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
include/uapi/linux/netfilter/nf_tables.h:       NFT_CT_DST_IP,
include/uapi/linux/netfilter/nf_tables.h:       NFT_CT_DST_IP6,

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-03 10:34             ` Pablo Neira Ayuso
@ 2025-09-03 11:51               ` Nikolaos Gkarlis
  0 siblings, 0 replies; 13+ messages in thread
From: Nikolaos Gkarlis @ 2025-09-03 11:51 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Florian Westphal, netfilter-devel

Thanks for clarifying. I'll look into preparing a userspace patch
when I get the chance.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
  2025-09-02 22:21       ` Florian Westphal
  2025-09-03 10:31       ` Pablo Neira Ayuso
@ 2025-09-03 13:18       ` kernel test robot
  2025-09-03 17:47       ` [syzbot ci] " syzbot ci
  2025-09-03 17:56       ` [PATCH v2] " kernel test robot
  4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-09-03 13:18 UTC (permalink / raw)
  To: Nikolaos Gkarlis, netfilter-devel
  Cc: llvm, oe-kbuild-all, pablo, fw, Nikolaos Gkarlis

Hi Nikolaos,

kernel test robot noticed the following build warnings:

[auto build test WARNING on netfilter-nf/main]
[also build test WARNING on linus/master v6.17-rc4 next-20250903]
[cannot apply to nf-next/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nikolaos-Gkarlis/netfilter-nft_ct-reject-ambiguous-conntrack-expressions-in-inet-tables/20250903-055737
base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git main
patch link:    https://lore.kernel.org/r/20250902215433.75568-1-nickgarlis%40gmail.com
patch subject: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
config: x86_64-rhel-9.4-rust (https://download.01.org/0day-ci/archive/20250903/202509032037.4hAJJ5wS-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
rustc: rustc 1.88.0 (6b00bc388 2025-06-23)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250903/202509032037.4hAJJ5wS-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509032037.4hAJJ5wS-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> net/netfilter/nft_ct.c:444:4: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
     444 |                         const struct nft_expr *curr, *last;
         |                         ^
   1 warning generated.


vim +444 net/netfilter/nft_ct.c

   382	
   383	static int nft_ct_get_init(const struct nft_ctx *ctx,
   384				   const struct nft_expr *expr,
   385				   const struct nlattr * const tb[])
   386	{
   387		struct nft_ct *priv = nft_expr_priv(expr);
   388		unsigned int len;
   389		int err;
   390	
   391		priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
   392		priv->dir = IP_CT_DIR_MAX;
   393		switch (priv->key) {
   394		case NFT_CT_DIRECTION:
   395			if (tb[NFTA_CT_DIRECTION] != NULL)
   396				return -EINVAL;
   397			len = sizeof(u8);
   398			break;
   399		case NFT_CT_STATE:
   400		case NFT_CT_STATUS:
   401	#ifdef CONFIG_NF_CONNTRACK_MARK
   402		case NFT_CT_MARK:
   403	#endif
   404	#ifdef CONFIG_NF_CONNTRACK_SECMARK
   405		case NFT_CT_SECMARK:
   406	#endif
   407		case NFT_CT_EXPIRATION:
   408			if (tb[NFTA_CT_DIRECTION] != NULL)
   409				return -EINVAL;
   410			len = sizeof(u32);
   411			break;
   412	#ifdef CONFIG_NF_CONNTRACK_LABELS
   413		case NFT_CT_LABELS:
   414			if (tb[NFTA_CT_DIRECTION] != NULL)
   415				return -EINVAL;
   416			len = NF_CT_LABELS_MAX_SIZE;
   417			break;
   418	#endif
   419		case NFT_CT_HELPER:
   420			if (tb[NFTA_CT_DIRECTION] != NULL)
   421				return -EINVAL;
   422			len = NF_CT_HELPER_NAME_LEN;
   423			break;
   424	
   425		case NFT_CT_L3PROTOCOL:
   426		case NFT_CT_PROTOCOL:
   427			/* For compatibility, do not report error if NFTA_CT_DIRECTION
   428			 * attribute is specified.
   429			 */
   430			len = sizeof(u8);
   431			break;
   432		case NFT_CT_SRC:
   433		case NFT_CT_DST:
   434			if (tb[NFTA_CT_DIRECTION] == NULL)
   435				return -EINVAL;
   436	
   437			switch (ctx->family) {
   438			case NFPROTO_IPV4:
   439				len = sizeof_field(struct nf_conntrack_tuple,
   440						   src.u3.ip);
   441				break;
   442			case NFPROTO_IPV6:
   443			case NFPROTO_INET:
 > 444				const struct nft_expr *curr, *last;
   445				bool meta_nfproto = false;
   446				if (!expr->rule)
   447					return -EINVAL;
   448	
   449				nft_rule_for_each_expr(curr, last, expr->rule) {
   450					if (curr == expr)
   451						break;
   452	
   453					if (curr->ops == &nft_meta_get_ops) {
   454						const struct nft_meta *meta = nft_expr_priv(curr);
   455						if (meta->key == NFT_META_NFPROTO) {
   456							meta_nfproto = true;
   457							break;
   458						}
   459					}
   460				}
   461				if (!meta_nfproto)
   462					return -EINVAL;
   463	
   464				len = sizeof_field(struct nf_conntrack_tuple,
   465						   src.u3.ip6);
   466				break;
   467			default:
   468				return -EAFNOSUPPORT;
   469			}
   470			break;
   471		case NFT_CT_SRC_IP:
   472		case NFT_CT_DST_IP:
   473			if (tb[NFTA_CT_DIRECTION] == NULL)
   474				return -EINVAL;
   475	
   476			len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip);
   477			break;
   478		case NFT_CT_SRC_IP6:
   479		case NFT_CT_DST_IP6:
   480			if (tb[NFTA_CT_DIRECTION] == NULL)
   481				return -EINVAL;
   482	
   483			len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip6);
   484			break;
   485		case NFT_CT_PROTO_SRC:
   486		case NFT_CT_PROTO_DST:
   487			if (tb[NFTA_CT_DIRECTION] == NULL)
   488				return -EINVAL;
   489			len = sizeof_field(struct nf_conntrack_tuple, src.u.all);
   490			break;
   491		case NFT_CT_BYTES:
   492		case NFT_CT_PKTS:
   493		case NFT_CT_AVGPKT:
   494			len = sizeof(u64);
   495			break;
   496	#ifdef CONFIG_NF_CONNTRACK_ZONES
   497		case NFT_CT_ZONE:
   498			len = sizeof(u16);
   499			break;
   500	#endif
   501		case NFT_CT_ID:
   502			if (tb[NFTA_CT_DIRECTION])
   503				return -EINVAL;
   504	
   505			len = sizeof(u32);
   506			break;
   507		default:
   508			return -EOPNOTSUPP;
   509		}
   510	
   511		if (tb[NFTA_CT_DIRECTION] != NULL) {
   512			priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
   513			switch (priv->dir) {
   514			case IP_CT_DIR_ORIGINAL:
   515			case IP_CT_DIR_REPLY:
   516				break;
   517			default:
   518				return -EINVAL;
   519			}
   520		}
   521	
   522		priv->len = len;
   523		err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
   524					       NFT_DATA_VALUE, len);
   525		if (err < 0)
   526			return err;
   527	
   528		err = nf_ct_netns_get(ctx->net, ctx->family);
   529		if (err < 0)
   530			return err;
   531	
   532		if (priv->key == NFT_CT_BYTES ||
   533		    priv->key == NFT_CT_PKTS  ||
   534		    priv->key == NFT_CT_AVGPKT)
   535			nf_ct_set_acct(ctx->net, true);
   536	
   537		return 0;
   538	}
   539	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [syzbot ci] Re: netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
                         ` (2 preceding siblings ...)
  2025-09-03 13:18       ` kernel test robot
@ 2025-09-03 17:47       ` syzbot ci
  2025-09-03 17:56       ` [PATCH v2] " kernel test robot
  4 siblings, 0 replies; 13+ messages in thread
From: syzbot ci @ 2025-09-03 17:47 UTC (permalink / raw)
  To: fw, netfilter-devel, nickgarlis, pablo; +Cc: syzbot, syzkaller-bugs

syzbot ci has tested the following series

[v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
https://lore.kernel.org/all/20250902215433.75568-1-nickgarlis@gmail.com
* [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables

and found the following issue:
KASAN: slab-out-of-bounds Write in nft_meta_inner_init

Full report is available here:
https://ci.syzbot.org/series/d9b8905e-8e5d-42de-8b7a-56fc81572df6

***

KASAN: slab-out-of-bounds Write in nft_meta_inner_init

tree:      nf-next
URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/netfilter/nf-next.git
base:      864ecc4a6dade82d3f70eab43dad0e277aa6fc78
arch:      amd64
compiler:  Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
config:    https://ci.syzbot.org/builds/b1146649-3f67-48cb-975c-62829433c8c5/config
C repro:   https://ci.syzbot.org/findings/d1f93a73-6b38-4a3b-9232-e80dea47a810/c_repro
syz repro: https://ci.syzbot.org/findings/d1f93a73-6b38-4a3b-9232-e80dea47a810/syz_repro

==================================================================
BUG: KASAN: slab-out-of-bounds in nft_meta_inner_init+0x1a7/0x1d0 net/netfilter/nft_meta.c:844
Write of size 1 at addr ffff88810d9f5a40 by task syz.0.17/5997

CPU: 1 UID: 0 PID: 5997 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0xca/0x240 mm/kasan/report.c:482
 kasan_report+0x118/0x150 mm/kasan/report.c:595
 nft_meta_inner_init+0x1a7/0x1d0 net/netfilter/nft_meta.c:844
 nft_inner_init+0x534/0x630 net/netfilter/nft_inner.c:388
 nf_tables_newexpr net/netfilter/nf_tables_api.c:3513 [inline]
 nf_tables_newrule+0x17b0/0x28a0 net/netfilter/nf_tables_api.c:4346
 nfnetlink_rcv_batch net/netfilter/nfnetlink.c:524 [inline]
 nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:647 [inline]
 nfnetlink_rcv+0x1132/0x2520 net/netfilter/nfnetlink.c:665
 netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
 netlink_unicast+0x82f/0x9e0 net/netlink/af_netlink.c:1346
 netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
 sock_sendmsg_nosec net/socket.c:714 [inline]
 __sock_sendmsg+0x21c/0x270 net/socket.c:729
 ____sys_sendmsg+0x505/0x830 net/socket.c:2614
 ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
 __sys_sendmsg net/socket.c:2700 [inline]
 __do_sys_sendmsg net/socket.c:2705 [inline]
 __se_sys_sendmsg net/socket.c:2703 [inline]
 __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f2d6c18ebe9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff1c4d5e58 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007f2d6c3c5fa0 RCX: 00007f2d6c18ebe9
RDX: 0000000000000000 RSI: 0000200000000000 RDI: 0000000000000003
RBP: 00007f2d6c211e19 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f2d6c3c5fa0 R14: 00007f2d6c3c5fa0 R15: 0000000000000003
 </TASK>

Allocated by task 5997:
 kasan_save_stack mm/kasan/common.c:47 [inline]
 kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
 poison_kmalloc_redzone mm/kasan/common.c:388 [inline]
 __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:405
 kasan_kmalloc include/linux/kasan.h:260 [inline]
 __do_kmalloc_node mm/slub.c:4365 [inline]
 __kmalloc_noprof+0x27a/0x4f0 mm/slub.c:4377
 kmalloc_noprof include/linux/slab.h:909 [inline]
 kzalloc_noprof include/linux/slab.h:1039 [inline]
 nf_tables_newrule+0x1503/0x28a0 net/netfilter/nf_tables_api.c:4328
 nfnetlink_rcv_batch net/netfilter/nfnetlink.c:524 [inline]
 nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:647 [inline]
 nfnetlink_rcv+0x1132/0x2520 net/netfilter/nfnetlink.c:665
 netlink_unicast_kernel net/netlink/af_netlink.c:1320 [inline]
 netlink_unicast+0x82f/0x9e0 net/netlink/af_netlink.c:1346
 netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1896
 sock_sendmsg_nosec net/socket.c:714 [inline]
 __sock_sendmsg+0x21c/0x270 net/socket.c:729
 ____sys_sendmsg+0x505/0x830 net/socket.c:2614
 ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
 __sys_sendmsg net/socket.c:2700 [inline]
 __do_sys_sendmsg net/socket.c:2705 [inline]
 __se_sys_sendmsg net/socket.c:2703 [inline]
 __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

The buggy address belongs to the object at ffff88810d9f5a00
 which belongs to the cache kmalloc-cg-64 of size 64
The buggy address is located 0 bytes to the right of
 allocated 64-byte region [ffff88810d9f5a00, ffff88810d9f5a40)

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff88810d9f5880 pfn:0x10d9f5
memcg:ffff88810dfc9601
flags: 0x57ff00000000000(node=1|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 057ff00000000000 ffff88801a449c80 ffffea0000f4b500 0000000000000002
raw: ffff88810d9f5880 000000008020001e 00000000f5000000 ffff88810dfc9601
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x52cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP), pid 5917, tgid 5917 (syz-executor), ts 70404800919, free_ts 68893144552
 set_page_owner include/linux/page_owner.h:32 [inline]
 post_alloc_hook+0x240/0x2a0 mm/page_alloc.c:1851
 prep_new_page mm/page_alloc.c:1859 [inline]
 get_page_from_freelist+0x21e4/0x22c0 mm/page_alloc.c:3858
 __alloc_frozen_pages_noprof+0x181/0x370 mm/page_alloc.c:5148
 alloc_pages_mpol+0x232/0x4a0 mm/mempolicy.c:2416
 alloc_slab_page mm/slub.c:2487 [inline]
 allocate_slab+0x8a/0x370 mm/slub.c:2655
 new_slab mm/slub.c:2709 [inline]
 ___slab_alloc+0xbeb/0x1410 mm/slub.c:3891
 __slab_alloc mm/slub.c:3981 [inline]
 __slab_alloc_node mm/slub.c:4056 [inline]
 slab_alloc_node mm/slub.c:4217 [inline]
 __do_kmalloc_node mm/slub.c:4364 [inline]
 __kvmalloc_node_noprof+0x429/0x5f0 mm/slub.c:5052
 alloc_netdev_mqs+0xc7c/0x11b0 net/core/dev.c:11944
 ip6_tnl_init_net+0x104/0x3b0 net/ipv6/ip6_tunnel.c:2292
 ops_init+0x35c/0x5c0 net/core/net_namespace.c:136
 setup_net+0x10c/0x320 net/core/net_namespace.c:438
 copy_net_ns+0x31b/0x4d0 net/core/net_namespace.c:570
 create_new_namespaces+0x3f3/0x720 kernel/nsproxy.c:110
 unshare_nsproxy_namespaces+0x11c/0x170 kernel/nsproxy.c:218
 ksys_unshare+0x4c8/0x8c0 kernel/fork.c:3127
 __do_sys_unshare kernel/fork.c:3198 [inline]
 __se_sys_unshare kernel/fork.c:3196 [inline]
 __x64_sys_unshare+0x38/0x50 kernel/fork.c:3196
page last free pid 976 tgid 976 stack trace:
 reset_page_owner include/linux/page_owner.h:25 [inline]
 free_pages_prepare mm/page_alloc.c:1395 [inline]
 __free_frozen_pages+0xbc4/0xd30 mm/page_alloc.c:2895
 kasan_depopulate_vmalloc_pte+0x74/0xa0 mm/kasan/shadow.c:472
 apply_to_pte_range mm/memory.c:3015 [inline]
 apply_to_pmd_range mm/memory.c:3059 [inline]
 apply_to_pud_range mm/memory.c:3095 [inline]
 apply_to_p4d_range mm/memory.c:3131 [inline]
 __apply_to_page_range+0xb92/0x1380 mm/memory.c:3167
 kasan_release_vmalloc+0xa2/0xd0 mm/kasan/shadow.c:593
 kasan_release_vmalloc_node mm/vmalloc.c:2249 [inline]
 purge_vmap_node+0x214/0x8f0 mm/vmalloc.c:2266
 __purge_vmap_area_lazy+0x7a4/0xb40 mm/vmalloc.c:2356
 drain_vmap_area_work+0x27/0x40 mm/vmalloc.c:2390
 process_one_work kernel/workqueue.c:3236 [inline]
 process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3319
 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
 kthread+0x711/0x8a0 kernel/kthread.c:463
 ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Memory state around the buggy address:
 ffff88810d9f5900: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
 ffff88810d9f5980: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
>ffff88810d9f5a00: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
                                           ^
 ffff88810d9f5a80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
 ffff88810d9f5b00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================


***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
  2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
                         ` (3 preceding siblings ...)
  2025-09-03 17:47       ` [syzbot ci] " syzbot ci
@ 2025-09-03 17:56       ` kernel test robot
  4 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2025-09-03 17:56 UTC (permalink / raw)
  To: Nikolaos Gkarlis, netfilter-devel
  Cc: llvm, oe-kbuild-all, pablo, fw, Nikolaos Gkarlis

Hi Nikolaos,

kernel test robot noticed the following build errors:

[auto build test ERROR on netfilter-nf/main]
[also build test ERROR on horms-ipvs/master linus/master v6.17-rc4 next-20250903]
[cannot apply to nf-next/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Nikolaos-Gkarlis/netfilter-nft_ct-reject-ambiguous-conntrack-expressions-in-inet-tables/20250903-055737
base:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git main
patch link:    https://lore.kernel.org/r/20250902215433.75568-1-nickgarlis%40gmail.com
patch subject: [PATCH v2] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20250904/202509040107.KmDmcM3p-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250904/202509040107.KmDmcM3p-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509040107.KmDmcM3p-lkp@intel.com/

All errors (new ones prefixed by >>):

>> net/netfilter/nft_ct.c:444:4: error: expected expression
     444 |                         const struct nft_expr *curr, *last;
         |                         ^
>> net/netfilter/nft_ct.c:449:27: error: use of undeclared identifier 'curr'
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                ^
>> net/netfilter/nft_ct.c:449:33: error: use of undeclared identifier 'last'
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                      ^
>> net/netfilter/nft_ct.c:449:27: error: use of undeclared identifier 'curr'
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                ^
>> net/netfilter/nft_ct.c:449:33: error: use of undeclared identifier 'last'
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                      ^
>> net/netfilter/nft_ct.c:449:27: error: use of undeclared identifier 'curr'
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                ^
>> net/netfilter/nft_ct.c:449:27: error: use of undeclared identifier 'curr'; did you mean 'err'?
     449 |                         nft_rule_for_each_expr(curr, last, expr->rule) {
         |                                                ^~~~
         |                                                err
   include/net/netfilter/nf_tables.h:1064:30: note: expanded from macro 'nft_rule_for_each_expr'
    1064 |              (expr) = nft_expr_next(expr))
         |                                     ^
   net/netfilter/nft_ct.c:389:6: note: 'err' declared here
     389 |         int err;
         |             ^
   net/netfilter/nft_ct.c:450:9: error: use of undeclared identifier 'curr'; did you mean 'err'?
     450 |                                 if (curr == expr)
         |                                     ^~~~
         |                                     err
   net/netfilter/nft_ct.c:389:6: note: 'err' declared here
     389 |         int err;
         |             ^
   net/netfilter/nft_ct.c:453:9: error: use of undeclared identifier 'curr'
     453 |                                 if (curr->ops == &nft_meta_get_ops) {
         |                                     ^
   net/netfilter/nft_ct.c:454:50: error: use of undeclared identifier 'curr'; did you mean 'err'?
     454 |                                         const struct nft_meta *meta = nft_expr_priv(curr);
         |                                                                                     ^~~~
         |                                                                                     err
   net/netfilter/nft_ct.c:389:6: note: 'err' declared here
     389 |         int err;
         |             ^
   10 errors generated.


vim +444 net/netfilter/nft_ct.c

   382	
   383	static int nft_ct_get_init(const struct nft_ctx *ctx,
   384				   const struct nft_expr *expr,
   385				   const struct nlattr * const tb[])
   386	{
   387		struct nft_ct *priv = nft_expr_priv(expr);
   388		unsigned int len;
   389		int err;
   390	
   391		priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
   392		priv->dir = IP_CT_DIR_MAX;
   393		switch (priv->key) {
   394		case NFT_CT_DIRECTION:
   395			if (tb[NFTA_CT_DIRECTION] != NULL)
   396				return -EINVAL;
   397			len = sizeof(u8);
   398			break;
   399		case NFT_CT_STATE:
   400		case NFT_CT_STATUS:
   401	#ifdef CONFIG_NF_CONNTRACK_MARK
   402		case NFT_CT_MARK:
   403	#endif
   404	#ifdef CONFIG_NF_CONNTRACK_SECMARK
   405		case NFT_CT_SECMARK:
   406	#endif
   407		case NFT_CT_EXPIRATION:
   408			if (tb[NFTA_CT_DIRECTION] != NULL)
   409				return -EINVAL;
   410			len = sizeof(u32);
   411			break;
   412	#ifdef CONFIG_NF_CONNTRACK_LABELS
   413		case NFT_CT_LABELS:
   414			if (tb[NFTA_CT_DIRECTION] != NULL)
   415				return -EINVAL;
   416			len = NF_CT_LABELS_MAX_SIZE;
   417			break;
   418	#endif
   419		case NFT_CT_HELPER:
   420			if (tb[NFTA_CT_DIRECTION] != NULL)
   421				return -EINVAL;
   422			len = NF_CT_HELPER_NAME_LEN;
   423			break;
   424	
   425		case NFT_CT_L3PROTOCOL:
   426		case NFT_CT_PROTOCOL:
   427			/* For compatibility, do not report error if NFTA_CT_DIRECTION
   428			 * attribute is specified.
   429			 */
   430			len = sizeof(u8);
   431			break;
   432		case NFT_CT_SRC:
   433		case NFT_CT_DST:
   434			if (tb[NFTA_CT_DIRECTION] == NULL)
   435				return -EINVAL;
   436	
   437			switch (ctx->family) {
   438			case NFPROTO_IPV4:
   439				len = sizeof_field(struct nf_conntrack_tuple,
   440						   src.u3.ip);
   441				break;
   442			case NFPROTO_IPV6:
   443			case NFPROTO_INET:
 > 444				const struct nft_expr *curr, *last;
   445				bool meta_nfproto = false;
   446				if (!expr->rule)
   447					return -EINVAL;
   448	
 > 449				nft_rule_for_each_expr(curr, last, expr->rule) {
   450					if (curr == expr)
   451						break;
   452	
   453					if (curr->ops == &nft_meta_get_ops) {
   454						const struct nft_meta *meta = nft_expr_priv(curr);
   455						if (meta->key == NFT_META_NFPROTO) {
   456							meta_nfproto = true;
   457							break;
   458						}
   459					}
   460				}
   461				if (!meta_nfproto)
   462					return -EINVAL;
   463	
   464				len = sizeof_field(struct nf_conntrack_tuple,
   465						   src.u3.ip6);
   466				break;
   467			default:
   468				return -EAFNOSUPPORT;
   469			}
   470			break;
   471		case NFT_CT_SRC_IP:
   472		case NFT_CT_DST_IP:
   473			if (tb[NFTA_CT_DIRECTION] == NULL)
   474				return -EINVAL;
   475	
   476			len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip);
   477			break;
   478		case NFT_CT_SRC_IP6:
   479		case NFT_CT_DST_IP6:
   480			if (tb[NFTA_CT_DIRECTION] == NULL)
   481				return -EINVAL;
   482	
   483			len = sizeof_field(struct nf_conntrack_tuple, src.u3.ip6);
   484			break;
   485		case NFT_CT_PROTO_SRC:
   486		case NFT_CT_PROTO_DST:
   487			if (tb[NFTA_CT_DIRECTION] == NULL)
   488				return -EINVAL;
   489			len = sizeof_field(struct nf_conntrack_tuple, src.u.all);
   490			break;
   491		case NFT_CT_BYTES:
   492		case NFT_CT_PKTS:
   493		case NFT_CT_AVGPKT:
   494			len = sizeof(u64);
   495			break;
   496	#ifdef CONFIG_NF_CONNTRACK_ZONES
   497		case NFT_CT_ZONE:
   498			len = sizeof(u16);
   499			break;
   500	#endif
   501		case NFT_CT_ID:
   502			if (tb[NFTA_CT_DIRECTION])
   503				return -EINVAL;
   504	
   505			len = sizeof(u32);
   506			break;
   507		default:
   508			return -EOPNOTSUPP;
   509		}
   510	
   511		if (tb[NFTA_CT_DIRECTION] != NULL) {
   512			priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
   513			switch (priv->dir) {
   514			case IP_CT_DIR_ORIGINAL:
   515			case IP_CT_DIR_REPLY:
   516				break;
   517			default:
   518				return -EINVAL;
   519			}
   520		}
   521	
   522		priv->len = len;
   523		err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
   524					       NFT_DATA_VALUE, len);
   525		if (err < 0)
   526			return err;
   527	
   528		err = nf_ct_netns_get(ctx->net, ctx->family);
   529		if (err < 0)
   530			return err;
   531	
   532		if (priv->key == NFT_CT_BYTES ||
   533		    priv->key == NFT_CT_PKTS  ||
   534		    priv->key == NFT_CT_AVGPKT)
   535			nf_ct_set_acct(ctx->net, true);
   536	
   537		return 0;
   538	}
   539	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2025-09-03 17:58 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-29  6:50 [PATCH] netfilter: nft_ct: reject ambiguous conntrack expressions in inet tables Nikolaos Gkarlis
2025-08-29 15:08 ` Florian Westphal
2025-08-29 21:59   ` Nick Garlis
2025-09-02 21:54     ` [PATCH v2] " Nikolaos Gkarlis
2025-09-02 22:21       ` Florian Westphal
2025-09-03  9:12         ` Nick Garlis
2025-09-03 10:13           ` Florian Westphal
2025-09-03 10:34             ` Pablo Neira Ayuso
2025-09-03 11:51               ` Nikolaos Gkarlis
2025-09-03 10:31       ` Pablo Neira Ayuso
2025-09-03 13:18       ` kernel test robot
2025-09-03 17:47       ` [syzbot ci] " syzbot ci
2025-09-03 17:56       ` [PATCH v2] " kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).