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: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
711d60a9e7
commit
0f5b3e85a3
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue