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

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

This is v3, I kept back an ipset fix and another to tigthen the xtables
interface to reject invalid combinations with the NFPROTO_ARP family.
They need a bit more discussion. I fixed the issues reported by AI on
patch 9 (add #ifdef to access ct zone, update nf_conntrack_broadcast
and patch 10 (use better Fixes: tag). Thanks!

The following patchset contains Netfilter fixes for *net*.

Note that most bugs fixed here stem from 2.6 days, the large PR is not
due to an increase in regressions.

1) Fix incorrect reject of set updates with nf_tables pipapo set
   avx2 backend.  This comes with a regression test in patch 2.
   From Florian Westphal.

2) nfnetlink_log needs to zero padding to prevent infoleak to userspace,
   from Weiming Shi.

3) xtables ip6t_rt module never validated that addrnr length is within the
   allowed array boundary. Reject bogus values.  From Ren Wei.

4) Fix high memory usage in rbtree set backend that was unwanted side-effect
   of the recently added binary search blob. From Pablo Neira Ayuso.

5) Patches 5 to 10, also from Pablo, address long-standing RCU safety bugs
   in conntracks handling of expectations: We can never safely defer
   a conntrack extension area without holding a reference. Yet expectation
   handling does so in multiple places.  Fix this by avoiding the need to
   look into the master conntrack to begin with and by extending locked
   sections in a few places.

11) Fix use of uninitialized rtp_addr in the sip conntrack helper,
    also from Weiming Shi.

12) Add stricter netlink policy checks in ctnetlink, from David Carlier.
    This avoids undefined behaviour when userspace provides huge wscale
    value.

netfilter pull request 26-03-26

* tag 'nf-26-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: ctnetlink: use netlink policy range checks
  netfilter: nf_conntrack_sip: fix use of uninitialized rtp_addr in process_sdp
  netfilter: nf_conntrack_expect: skip expectations in other netns via proc
  netfilter: nf_conntrack_expect: store netns and zone in expectation
  netfilter: ctnetlink: ensure safe access to master conntrack
  netfilter: nf_conntrack_expect: use expect->helper
  netfilter: nf_conntrack_expect: honor expectation helper field
  netfilter: nft_set_rbtree: revisit array resize logic
  netfilter: ip6t_rt: reject oversized addrnr in rt_mt6_check()
  netfilter: nfnetlink_log: fix uninitialized padding leak in NFULA_PAYLOAD
  selftests: netfilter: nft_concat_range.sh: add check for flush+reload bug
  netfilter: nft_set_pipapo_avx2: don't return non-matching entry on expiry
====================

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


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents deec4f7b 8f15b507
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -83,6 +83,11 @@ void nf_conntrack_lock(spinlock_t *lock);

extern spinlock_t nf_conntrack_expect_lock;

static inline void lockdep_nfct_expect_lock_held(void)
{
	lockdep_assert_held(&nf_conntrack_expect_lock);
}

/* ctnetlink code shared by both ctnetlink and nf_conntrack_bpf */

static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout)
+18 −2
Original line number Diff line number Diff line
@@ -22,10 +22,16 @@ struct nf_conntrack_expect {
	/* Hash member */
	struct hlist_node hnode;

	/* Network namespace */
	possible_net_t net;

	/* We expect this tuple, with the following mask */
	struct nf_conntrack_tuple tuple;
	struct nf_conntrack_tuple_mask mask;

#ifdef CONFIG_NF_CONNTRACK_ZONES
	struct nf_conntrack_zone zone;
#endif
	/* Usage count. */
	refcount_t use;

@@ -40,7 +46,7 @@ struct nf_conntrack_expect {
			 struct nf_conntrack_expect *this);

	/* Helper to assign to new connection */
	struct nf_conntrack_helper *helper;
	struct nf_conntrack_helper __rcu *helper;

	/* The conntrack of the master connection */
	struct nf_conn *master;
@@ -62,7 +68,17 @@ struct nf_conntrack_expect {

static inline struct net *nf_ct_exp_net(struct nf_conntrack_expect *exp)
{
	return nf_ct_net(exp->master);
	return read_pnet(&exp->net);
}

static inline bool nf_ct_exp_zone_equal_any(const struct nf_conntrack_expect *a,
					    const struct nf_conntrack_zone *b)
{
#ifdef CONFIG_NF_CONNTRACK_ZONES
	return a->zone.id == b->id;
#else
	return true;
#endif
}

#define NF_CT_EXP_POLICY_NAME_LEN	16
+4 −0
Original line number Diff line number Diff line
@@ -159,5 +159,9 @@ enum ip_conntrack_expect_events {
#define NF_CT_EXPECT_INACTIVE		0x2
#define NF_CT_EXPECT_USERSPACE		0x4

#ifdef __KERNEL__
#define NF_CT_EXPECT_MASK	(NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE | \
				 NF_CT_EXPECT_USERSPACE)
#endif

#endif /* _UAPI_NF_CONNTRACK_COMMON_H */
+4 −0
Original line number Diff line number Diff line
@@ -157,6 +157,10 @@ static int rt_mt6_check(const struct xt_mtchk_param *par)
		pr_debug("unknown flags %X\n", rtinfo->invflags);
		return -EINVAL;
	}
	if (rtinfo->addrnr > IP6T_RT_HOPS) {
		pr_debug("too many addresses specified\n");
		return -EINVAL;
	}
	if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
	    (!(rtinfo->flags & IP6T_RT_TYP) ||
	     (rtinfo->rt_type != 0) ||
+6 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
				unsigned int timeout)
{
	const struct nf_conntrack_helper *helper;
	struct net *net = read_pnet(&ct->ct_net);
	struct nf_conntrack_expect *exp;
	struct iphdr *iph = ip_hdr(skb);
	struct rtable *rt = skb_rtable(skb);
@@ -70,8 +71,11 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
	exp->expectfn             = NULL;
	exp->flags                = NF_CT_EXPECT_PERMANENT;
	exp->class		  = NF_CT_EXPECT_CLASS_DEFAULT;
	exp->helper               = NULL;

	rcu_assign_pointer(exp->helper, helper);
	write_pnet(&exp->net, net);
#ifdef CONFIG_NF_CONNTRACK_ZONES
	exp->zone = ct->zone;
#endif
	nf_ct_expect_related(exp, 0);
	nf_ct_expect_put(exp);

Loading