Skip to content

Commit e98cda7

Browse files
committed
Florian Westphal says: ==================== netfilter: updates for net 1) its not possible to attach conntrack labels via ctnetlink unless one creates a dummy 'ct labels set' rule in nftables. This is an oversight, the 'ruleset tests presence, userspace (netlink) sets' use-case is valid and should 'just work'. Always broken since this got added in Linux 4.7. 2) nft_connlimit reads count value without holding the relevant lock, add a READ_ONCE annotation. From Fernando Fernandez Mancera. 3) There is a long-standing bug (since 4.12) in nftables helper infra when NAT is in use: if the helper gets assigned after the nat binding was set up, we fail to initialise the 'seqadj' extension, which is needed in case NAT payload rewrites need to add (or remove) from the packet payload. Fix from Andrii Melnychenko. * tag 'nf-25-10-29' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: nft_ct: add seqadj extension for natted connections netfilter: nft_connlimit: fix possible data race on connection count netfilter: nft_ct: enable labels for get case too ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 2985749 + 90918e3 commit e98cda7

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

net/netfilter/nft_connlimit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,
4848
return;
4949
}
5050

51-
count = priv->list->count;
51+
count = READ_ONCE(priv->list->count);
5252

5353
if ((count > priv->limit) ^ priv->invert) {
5454
regs->verdict.code = NFT_BREAK;

net/netfilter/nft_ct.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <net/netfilter/nf_conntrack_timeout.h>
2323
#include <net/netfilter/nf_conntrack_l4proto.h>
2424
#include <net/netfilter/nf_conntrack_expect.h>
25+
#include <net/netfilter/nf_conntrack_seqadj.h>
2526

2627
struct nft_ct_helper_obj {
2728
struct nf_conntrack_helper *helper4;
@@ -379,6 +380,14 @@ static bool nft_ct_tmpl_alloc_pcpu(void)
379380
}
380381
#endif
381382

383+
static void __nft_ct_get_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
384+
{
385+
#ifdef CONFIG_NF_CONNTRACK_LABELS
386+
if (priv->key == NFT_CT_LABELS)
387+
nf_connlabels_put(ctx->net);
388+
#endif
389+
}
390+
382391
static int nft_ct_get_init(const struct nft_ctx *ctx,
383392
const struct nft_expr *expr,
384393
const struct nlattr * const tb[])
@@ -413,6 +422,10 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
413422
if (tb[NFTA_CT_DIRECTION] != NULL)
414423
return -EINVAL;
415424
len = NF_CT_LABELS_MAX_SIZE;
425+
426+
err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
427+
if (err)
428+
return err;
416429
break;
417430
#endif
418431
case NFT_CT_HELPER:
@@ -494,26 +507,30 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
494507
case IP_CT_DIR_REPLY:
495508
break;
496509
default:
497-
return -EINVAL;
510+
err = -EINVAL;
511+
goto err;
498512
}
499513
}
500514

501515
priv->len = len;
502516
err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL,
503517
NFT_DATA_VALUE, len);
504518
if (err < 0)
505-
return err;
519+
goto err;
506520

507521
err = nf_ct_netns_get(ctx->net, ctx->family);
508522
if (err < 0)
509-
return err;
523+
goto err;
510524

511525
if (priv->key == NFT_CT_BYTES ||
512526
priv->key == NFT_CT_PKTS ||
513527
priv->key == NFT_CT_AVGPKT)
514528
nf_ct_set_acct(ctx->net, true);
515529

516530
return 0;
531+
err:
532+
__nft_ct_get_destroy(ctx, priv);
533+
return err;
517534
}
518535

519536
static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
@@ -626,6 +643,9 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
626643
static void nft_ct_get_destroy(const struct nft_ctx *ctx,
627644
const struct nft_expr *expr)
628645
{
646+
struct nft_ct *priv = nft_expr_priv(expr);
647+
648+
__nft_ct_get_destroy(ctx, priv);
629649
nf_ct_netns_put(ctx->net, ctx->family);
630650
}
631651

@@ -1173,6 +1193,10 @@ static void nft_ct_helper_obj_eval(struct nft_object *obj,
11731193
if (help) {
11741194
rcu_assign_pointer(help->helper, to_assign);
11751195
set_bit(IPS_HELPER_BIT, &ct->status);
1196+
1197+
if ((ct->status & IPS_NAT_MASK) && !nfct_seqadj(ct))
1198+
if (!nfct_seqadj_ext_add(ct))
1199+
regs->verdict.code = NF_DROP;
11761200
}
11771201
}
11781202

0 commit comments

Comments
 (0)