Commit 69b1b21a authored by Paolo Abeni's avatar Paolo Abeni
Browse files
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following batch contains Netfilter fixes for net:

1) Three patches to enhance conntrack selftests for resize and clash
   resolution, from Florian Westphal.

2) Expand nft_concat_range.sh selftest to improve coverage from error
   path, from Florian Westphal.

3) Hide clash bit to userspace from netlink dumps until there is a
   good reason to expose, from Florian Westphal.

4) Revert notification for device registration/unregistration for
   nftables basechains and flowtables, we decided to go for a better
   way to handle this through the nfnetlink_hook infrastructure which
   will come via nf-next, patch from Phil Sutter.

5) Fix crash in conntrack due to race related to SLAB_TYPESAFE_BY_RCU
   that results in removing a recycled object that is not yet in the
   hashes. Move IPS_CONFIRM setting after the object is in the hashes.
   From Florian Westphal.

netfilter pull request 25-07-17

* tag 'nf-25-07-17' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nf_conntrack: fix crash due to removal of uninitialised entry
  Revert "netfilter: nf_tables: Add notifications for hook changes"
  netfilter: nf_tables: hide clash bit from userspace
  selftests: netfilter: nft_concat_range.sh: send packets to empty set
  selftests: netfilter: conntrack_resize.sh: also use udpclash tool
  selftests: netfilter: add conntrack clash resolution test case
  selftests: netfilter: conntrack_resize.sh: extend resize test
====================

Link: https://patch.msgid.link/20250717095808.41725-1-pablo@netfilter.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 9f735b6f 2d72afb3
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -306,8 +306,19 @@ static inline bool nf_ct_is_expired(const struct nf_conn *ct)
/* use after obtaining a reference count */
static inline bool nf_ct_should_gc(const struct nf_conn *ct)
{
	return nf_ct_is_expired(ct) && nf_ct_is_confirmed(ct) &&
	       !nf_ct_is_dying(ct);
	if (!nf_ct_is_confirmed(ct))
		return false;

	/* load ct->timeout after is_confirmed() test.
	 * Pairs with __nf_conntrack_confirm() which:
	 * 1. Increases ct->timeout value
	 * 2. Inserts ct into rcu hlist
	 * 3. Sets the confirmed bit
	 * 4. Unlocks the hlist lock
	 */
	smp_acquire__after_ctrl_dep();

	return nf_ct_is_expired(ct) && !nf_ct_is_dying(ct);
}

#define	NF_CT_DAY	(86400 * HZ)
+0 −5
Original line number Diff line number Diff line
@@ -1142,11 +1142,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set);
int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);
void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain);

struct nft_hook;
void nf_tables_chain_device_notify(const struct nft_chain *chain,
				   const struct nft_hook *hook,
				   const struct net_device *dev, int event);

enum nft_chain_types {
	NFT_CHAIN_T_DEFAULT = 0,
	NFT_CHAIN_T_ROUTE,
+0 −10
Original line number Diff line number Diff line
@@ -142,8 +142,6 @@ enum nf_tables_msg_types {
	NFT_MSG_DESTROYOBJ,
	NFT_MSG_DESTROYFLOWTABLE,
	NFT_MSG_GETSETELEM_RESET,
	NFT_MSG_NEWDEV,
	NFT_MSG_DELDEV,
	NFT_MSG_MAX,
};

@@ -1786,18 +1784,10 @@ enum nft_synproxy_attributes {
 * enum nft_device_attributes - nf_tables device netlink attributes
 *
 * @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
 * @NFTA_DEVICE_TABLE: table containing the flowtable or chain hooking into the device (NLA_STRING)
 * @NFTA_DEVICE_FLOWTABLE: flowtable hooking into the device (NLA_STRING)
 * @NFTA_DEVICE_CHAIN: chain hooking into the device (NLA_STRING)
 * @NFTA_DEVICE_SPEC: hook spec matching the device (NLA_STRING)
 */
enum nft_devices_attributes {
	NFTA_DEVICE_UNSPEC,
	NFTA_DEVICE_NAME,
	NFTA_DEVICE_TABLE,
	NFTA_DEVICE_FLOWTABLE,
	NFTA_DEVICE_CHAIN,
	NFTA_DEVICE_SPEC,
	__NFTA_DEVICE_MAX
};
#define NFTA_DEVICE_MAX		(__NFTA_DEVICE_MAX - 1)
+0 −2
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@ enum nfnetlink_groups {
#define NFNLGRP_ACCT_QUOTA		NFNLGRP_ACCT_QUOTA
	NFNLGRP_NFTRACE,
#define NFNLGRP_NFTRACE			NFNLGRP_NFTRACE
	NFNLGRP_NFT_DEV,
#define NFNLGRP_NFT_DEV			NFNLGRP_NFT_DEV
	__NFNLGRP_MAX,
};
#define NFNLGRP_MAX	(__NFNLGRP_MAX - 1)
+20 −6
Original line number Diff line number Diff line
@@ -1124,6 +1124,12 @@ static int nf_ct_resolve_clash_harder(struct sk_buff *skb, u32 repl_idx)

	hlist_nulls_add_head_rcu(&loser_ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
				 &nf_conntrack_hash[repl_idx]);
	/* confirmed bit must be set after hlist add, not before:
	 * loser_ct can still be visible to other cpu due to
	 * SLAB_TYPESAFE_BY_RCU.
	 */
	smp_mb__before_atomic();
	set_bit(IPS_CONFIRMED_BIT, &loser_ct->status);

	NF_CT_STAT_INC(net, clash_resolve);
	return NF_ACCEPT;
@@ -1260,8 +1266,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
	 * user context, else we insert an already 'dead' hash, blocking
	 * further use of that particular connection -JM.
	 */
	ct->status |= IPS_CONFIRMED;

	if (unlikely(nf_ct_is_dying(ct))) {
		NF_CT_STAT_INC(net, insert_failed);
		goto dying;
@@ -1293,7 +1297,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
		}
	}

	/* Timer relative to confirmation time, not original
	/* Timeout is relative to confirmation time, not original
	   setting time, otherwise we'd get timer wrap in
	   weird delay cases. */
	ct->timeout += nfct_time_stamp;
@@ -1301,11 +1305,21 @@ __nf_conntrack_confirm(struct sk_buff *skb)
	__nf_conntrack_insert_prepare(ct);

	/* Since the lookup is lockless, hash insertion must be done after
	 * starting the timer and setting the CONFIRMED bit. The RCU barriers
	 * guarantee that no other CPU can find the conntrack before the above
	 * stores are visible.
	 * setting ct->timeout. The RCU barriers guarantee that no other CPU
	 * can find the conntrack before the above stores are visible.
	 */
	__nf_conntrack_hash_insert(ct, hash, reply_hash);

	/* IPS_CONFIRMED unset means 'ct not (yet) in hash', conntrack lookups
	 * skip entries that lack this bit.  This happens when a CPU is looking
	 * at a stale entry that is being recycled due to SLAB_TYPESAFE_BY_RCU
	 * or when another CPU encounters this entry right after the insertion
	 * but before the set-confirm-bit below.  This bit must not be set until
	 * after __nf_conntrack_hash_insert().
	 */
	smp_mb__before_atomic();
	set_bit(IPS_CONFIRMED_BIT, &ct->status);

	nf_conntrack_double_unlock(hash, reply_hash);
	local_bh_enable();

Loading