Commit e14575fa authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_conntrack: use rcu accessors where needed



Sparse complains about direct access to the 'helper' and timeout members.
Both have __rcu annotation, so use the accessors.

xt_CT is fine, accesses occur before the structure is visible to other
cpus.  Switch to rcu accessors there as well to reduce noise.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 6976890e
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
				enum ip_conntrack_info ctinfo,
				unsigned int timeout)
{
	const struct nf_conntrack_helper *helper;
	struct nf_conntrack_expect *exp;
	struct iphdr *iph = ip_hdr(skb);
	struct rtable *rt = skb_rtable(skb);
@@ -58,7 +59,10 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
		goto out;

	exp->tuple                = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
	exp->tuple.src.u.udp.port = help->helper->tuple.src.u.udp.port;

	helper = rcu_dereference(help->helper);
	if (helper)
		exp->tuple.src.u.udp.port = helper->tuple.src.u.udp.port;

	exp->mask.src.u3.ip       = mask;
	exp->mask.src.u.udp.port  = htons(0xFFFF);
+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
	if (tmpl != NULL) {
		help = nfct_help(tmpl);
		if (help != NULL) {
			helper = help->helper;
			helper = rcu_dereference(help->helper);
			set_bit(IPS_HELPER_BIT, &ct->status);
		}
	}
+7 −2
Original line number Diff line number Diff line
@@ -2004,7 +2004,7 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
	}

	if (help) {
		if (help->helper == helper) {
		if (rcu_access_pointer(help->helper) == helper) {
			/* update private helper data if allowed. */
			if (helper->from_nlattr)
				helper->from_nlattr(helpinfo, ct);
@@ -3412,12 +3412,17 @@ static int ctnetlink_get_expect(struct sk_buff *skb,

static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
{
	struct nf_conntrack_helper *helper;
	const struct nf_conn_help *m_help;
	const char *name = data;

	m_help = nfct_help(exp->master);

	return strcmp(m_help->helper->name, name) == 0;
	helper = rcu_dereference(m_help->helper);
	if (!helper)
		return false;

	return strcmp(helper->name, name) == 0;
}

static bool expect_iter_all(struct nf_conntrack_expect *exp, void *data)
+6 −1
Original line number Diff line number Diff line
@@ -1229,6 +1229,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
	struct nf_conntrack_expect *exp;
	union nf_inet_addr *saddr, daddr;
	const struct nf_nat_sip_hooks *hooks;
	struct nf_conntrack_helper *helper;
	__be16 port;
	u8 proto;
	unsigned int expires = 0;
@@ -1289,10 +1290,14 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
	if (sip_direct_signalling)
		saddr = &ct->tuplehash[!dir].tuple.src.u3;

	helper = rcu_dereference(nfct_help(ct)->helper);
	if (!helper)
		return NF_DROP;

	nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct),
			  saddr, &daddr, proto, NULL, &port);
	exp->timeout.expires = sip_timeout * HZ;
	exp->helper = nfct_help(ct)->helper;
	exp->helper = helper;
	exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;

	hooks = rcu_dereference(nf_nat_sip_hooks);
+13 −3
Original line number Diff line number Diff line
@@ -29,8 +29,14 @@ static int untimeout(struct nf_conn *ct, void *timeout)
{
	struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);

	if (timeout_ext && (!timeout || timeout_ext->timeout == timeout))
	if (timeout_ext) {
		const struct nf_ct_timeout *t;

		t = rcu_access_pointer(timeout_ext->timeout);

		if (!timeout || t == timeout)
			RCU_INIT_POINTER(timeout_ext->timeout, NULL);
	}

	/* We are not intended to delete this conntrack. */
	return 0;
@@ -127,7 +133,11 @@ void nf_ct_destroy_timeout(struct nf_conn *ct)
	if (h) {
		timeout_ext = nf_ct_timeout_find(ct);
		if (timeout_ext) {
			h->timeout_put(timeout_ext->timeout);
			struct nf_ct_timeout *t;

			t = rcu_dereference(timeout_ext->timeout);
			if (t)
				h->timeout_put(t);
			RCU_INIT_POINTER(timeout_ext->timeout, NULL);
		}
	}
Loading