Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f5b3e85 authored by Patrick McHardy's avatar Patrick McHardy
Browse files

netfilter: ctnetlink: fix rcu context imbalance



Introduced by 7ec47496 (netfilter: ctnetlink: cleanup master conntrack assignation):

net/netfilter/nf_conntrack_netlink.c:1275:2: warning: context imbalance in 'ctnetlink_create_conntrack' - different lock contexts for basic block

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 711d60a9
Loading
Loading
Loading
Loading
+23 −34
Original line number Original line Diff line number Diff line
@@ -1146,7 +1146,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);


	if (!cda[CTA_TIMEOUT])
	if (!cda[CTA_TIMEOUT])
		goto err;
		goto err1;
	ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
	ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));


	ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
	ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
@@ -1157,10 +1157,8 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
 		char *helpname;
 		char *helpname;
 
 
 		err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
 		err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
 		if (err < 0) {
 		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}


		helper = __nf_conntrack_helper_find_byname(helpname);
		helper = __nf_conntrack_helper_find_byname(helpname);
		if (helper == NULL) {
		if (helper == NULL) {
@@ -1168,28 +1166,26 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
#ifdef CONFIG_MODULES
#ifdef CONFIG_MODULES
			if (request_module("nfct-helper-%s", helpname) < 0) {
			if (request_module("nfct-helper-%s", helpname) < 0) {
				err = -EOPNOTSUPP;
				err = -EOPNOTSUPP;
				goto err;
				goto err1;
			}
			}


			rcu_read_lock();
			rcu_read_lock();
			helper = __nf_conntrack_helper_find_byname(helpname);
			helper = __nf_conntrack_helper_find_byname(helpname);
			if (helper) {
			if (helper) {
				rcu_read_unlock();
				err = -EAGAIN;
				err = -EAGAIN;
				goto err;
				goto err2;
			}
			}
			rcu_read_unlock();
			rcu_read_unlock();
#endif
#endif
			err = -EOPNOTSUPP;
			err = -EOPNOTSUPP;
			goto err;
			goto err1;
		} else {
		} else {
			struct nf_conn_help *help;
			struct nf_conn_help *help;


			help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
			help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
			if (help == NULL) {
			if (help == NULL) {
				rcu_read_unlock();
				err = -ENOMEM;
				err = -ENOMEM;
				goto err;
				goto err2;
			}
			}


			/* not in hash table yet so not strictly necessary */
			/* not in hash table yet so not strictly necessary */
@@ -1198,44 +1194,34 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
	} else {
	} else {
		/* try an implicit helper assignation */
		/* try an implicit helper assignation */
		err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
		err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC);
		if (err < 0) {
		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}
	}
	}


	if (cda[CTA_STATUS]) {
	if (cda[CTA_STATUS]) {
		err = ctnetlink_change_status(ct, cda);
		err = ctnetlink_change_status(ct, cda);
		if (err < 0) {
		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}
	}
	}


	if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
	if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
		err = ctnetlink_change_nat(ct, cda);
		err = ctnetlink_change_nat(ct, cda);
		if (err < 0) {
		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}
	}
	}


#ifdef CONFIG_NF_NAT_NEEDED
#ifdef CONFIG_NF_NAT_NEEDED
	if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) {
	if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) {
		err = ctnetlink_change_nat_seq_adj(ct, cda);
		err = ctnetlink_change_nat_seq_adj(ct, cda);
		if (err < 0) {
		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}
	}
	}
#endif
#endif


	if (cda[CTA_PROTOINFO]) {
	if (cda[CTA_PROTOINFO]) {
		err = ctnetlink_change_protoinfo(ct, cda);
		err = ctnetlink_change_protoinfo(ct, cda);
		if (err < 0) {
		if (err < 0)
			rcu_read_unlock();
			goto err2;
			goto err;
		}
	}
	}


	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
	nf_ct_acct_ext_add(ct, GFP_ATOMIC);
@@ -1253,12 +1239,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],


		err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3);
		err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3);
		if (err < 0)
		if (err < 0)
			goto err;
			goto err2;


		master_h = __nf_conntrack_find(&init_net, &master);
		master_h = __nf_conntrack_find(&init_net, &master);
		if (master_h == NULL) {
		if (master_h == NULL) {
			err = -ENOENT;
			err = -ENOENT;
			goto err;
			goto err2;
		}
		}
		master_ct = nf_ct_tuplehash_to_ctrack(master_h);
		master_ct = nf_ct_tuplehash_to_ctrack(master_h);
		nf_conntrack_get(&master_ct->ct_general);
		nf_conntrack_get(&master_ct->ct_general);
@@ -1271,7 +1257,10 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
	rcu_read_unlock();
	rcu_read_unlock();


	return ct;
	return ct;
err:

err2:
	rcu_read_unlock();
err1:
	nf_conntrack_free(ct);
	nf_conntrack_free(ct);
	return ERR_PTR(err);
	return ERR_PTR(err);
}
}