Commit 2158cfb0 authored by David S. Miller's avatar David S. Miller
Browse files


Pablo Neira Ayuso says:

====================
The following patchset contains late Netfilter fixes for net:

1) Use READ_ONCE()/WRITE_ONCE() to update ct->mark, from Daniel Xu.
   Not reported by syzbot, but I presume KASAN would trigger post
   a splat on this. This is a rather old issue, predating git history.

2) Do not set up extensions for set element with end interval flag
   set on. This leads to bogusly skipping this elements as expired
   when listing the set/map to userspace as well as increasing
   memory consumpton when stateful expressions are used. This issue
   has been present since 4.18, when timeout support for rbtree set
   was added.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 19d04a94 33c7aba0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
	key->ct_zone = ct->zone.id;
#endif
#if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
	key->ct_mark = ct->mark;
	key->ct_mark = READ_ONCE(ct->mark);
#endif

	cl = nf_ct_labels_find(ct);
+2 −2
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)

	switch (ctinfo) {
	case IP_CT_NEW:
		ct->mark = hash;
		WRITE_ONCE(ct->mark, hash);
		break;
	case IP_CT_RELATED:
	case IP_CT_RELATED_REPLY:
@@ -452,7 +452,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
#ifdef DEBUG
	nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
#endif
	pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
	pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark));
	if (!clusterip_responsible(cipinfo->config, hash)) {
		pr_debug("not responsible\n");
		return NF_DROP;
+1 −1
Original line number Diff line number Diff line
@@ -1781,7 +1781,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
			}

#ifdef CONFIG_NF_CONNTRACK_MARK
			ct->mark = exp->master->mark;
			ct->mark = READ_ONCE(exp->master->mark);
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
			ct->secmark = exp->master->secmark;
+14 −10
Original line number Diff line number Diff line
@@ -328,9 +328,9 @@ ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
}

#ifdef CONFIG_NF_CONNTRACK_MARK
static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
{
	if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
		goto nla_put_failure;
	return 0;

@@ -543,7 +543,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
{
	if (ctnetlink_dump_status(skb, ct) < 0 ||
	    ctnetlink_dump_mark(skb, ct) < 0 ||
	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
	    ctnetlink_dump_secctx(skb, ct) < 0 ||
	    ctnetlink_dump_id(skb, ct) < 0 ||
	    ctnetlink_dump_use(skb, ct) < 0 ||
@@ -722,6 +722,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
	struct sk_buff *skb;
	unsigned int type;
	unsigned int flags = 0, group;
	u32 mark;
	int err;

	if (events & (1 << IPCT_DESTROY)) {
@@ -826,8 +827,9 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
	}

#ifdef CONFIG_NF_CONNTRACK_MARK
	if ((events & (1 << IPCT_MARK) || ct->mark)
	    && ctnetlink_dump_mark(skb, ct) < 0)
	mark = READ_ONCE(ct->mark);
	if ((events & (1 << IPCT_MARK) || mark) &&
	    ctnetlink_dump_mark(skb, mark) < 0)
		goto nla_put_failure;
#endif
	nlmsg_end(skb, nlh);
@@ -1154,7 +1156,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
	}

#ifdef CONFIG_NF_CONNTRACK_MARK
	if ((ct->mark & filter->mark.mask) != filter->mark.val)
	if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val)
		goto ignore_entry;
#endif
	status = (u32)READ_ONCE(ct->status);
@@ -2002,9 +2004,9 @@ static void ctnetlink_change_mark(struct nf_conn *ct,
		mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));

	mark = ntohl(nla_get_be32(cda[CTA_MARK]));
	newmark = (ct->mark & mask) ^ mark;
	if (newmark != ct->mark)
		ct->mark = newmark;
	newmark = (READ_ONCE(ct->mark) & mask) ^ mark;
	if (newmark != READ_ONCE(ct->mark))
		WRITE_ONCE(ct->mark, newmark);
}
#endif

@@ -2669,6 +2671,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
{
	const struct nf_conntrack_zone *zone;
	struct nlattr *nest_parms;
	u32 mark;

	zone = nf_ct_zone(ct);

@@ -2730,7 +2733,8 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
		goto nla_put_failure;

#ifdef CONFIG_NF_CONNTRACK_MARK
	if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
	mark = READ_ONCE(ct->mark);
	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
		goto nla_put_failure;
#endif
	if (ctnetlink_dump_labels(skb, ct) < 0)
+1 −1
Original line number Diff line number Diff line
@@ -366,7 +366,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
		goto release;

#if defined(CONFIG_NF_CONNTRACK_MARK)
	seq_printf(s, "mark=%u ", ct->mark);
	seq_printf(s, "mark=%u ", READ_ONCE(ct->mark));
#endif

	ct_show_secctx(s, ct);
Loading