diff options
author | Patrick McHardy <kaber@trash.net> | 2009-03-18 12:36:40 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-03-18 12:36:40 -0400 |
commit | 0f5b3e85a3716efebb0150ebb7c6d022e2bf17d7 (patch) | |
tree | 6c78ac1adb199f76acab6b9911e852d1f963c0b6 /net | |
parent | 711d60a9e7f88e394ccca10f5fc83f95f0cea5b1 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 735ea9c1a96..d1fe9d15ac5 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1146,7 +1146,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1146 | return ERR_PTR(-ENOMEM); | 1146 | return ERR_PTR(-ENOMEM); |
1147 | 1147 | ||
1148 | if (!cda[CTA_TIMEOUT]) | 1148 | if (!cda[CTA_TIMEOUT]) |
1149 | goto err; | 1149 | goto err1; |
1150 | ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT])); | 1150 | ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT])); |
1151 | 1151 | ||
1152 | ct->timeout.expires = jiffies + ct->timeout.expires * HZ; | 1152 | ct->timeout.expires = jiffies + ct->timeout.expires * HZ; |
@@ -1157,10 +1157,8 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1157 | char *helpname; | 1157 | char *helpname; |
1158 | 1158 | ||
1159 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); | 1159 | err = ctnetlink_parse_help(cda[CTA_HELP], &helpname); |
1160 | if (err < 0) { | 1160 | if (err < 0) |
1161 | rcu_read_unlock(); | 1161 | goto err2; |
1162 | goto err; | ||
1163 | } | ||
1164 | 1162 | ||
1165 | helper = __nf_conntrack_helper_find_byname(helpname); | 1163 | helper = __nf_conntrack_helper_find_byname(helpname); |
1166 | if (helper == NULL) { | 1164 | if (helper == NULL) { |
@@ -1168,28 +1166,26 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1168 | #ifdef CONFIG_MODULES | 1166 | #ifdef CONFIG_MODULES |
1169 | if (request_module("nfct-helper-%s", helpname) < 0) { | 1167 | if (request_module("nfct-helper-%s", helpname) < 0) { |
1170 | err = -EOPNOTSUPP; | 1168 | err = -EOPNOTSUPP; |
1171 | goto err; | 1169 | goto err1; |
1172 | } | 1170 | } |
1173 | 1171 | ||
1174 | rcu_read_lock(); | 1172 | rcu_read_lock(); |
1175 | helper = __nf_conntrack_helper_find_byname(helpname); | 1173 | helper = __nf_conntrack_helper_find_byname(helpname); |
1176 | if (helper) { | 1174 | if (helper) { |
1177 | rcu_read_unlock(); | ||
1178 | err = -EAGAIN; | 1175 | err = -EAGAIN; |
1179 | goto err; | 1176 | goto err2; |
1180 | } | 1177 | } |
1181 | rcu_read_unlock(); | 1178 | rcu_read_unlock(); |
1182 | #endif | 1179 | #endif |
1183 | err = -EOPNOTSUPP; | 1180 | err = -EOPNOTSUPP; |
1184 | goto err; | 1181 | goto err1; |
1185 | } else { | 1182 | } else { |
1186 | struct nf_conn_help *help; | 1183 | struct nf_conn_help *help; |
1187 | 1184 | ||
1188 | help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); | 1185 | help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); |
1189 | if (help == NULL) { | 1186 | if (help == NULL) { |
1190 | rcu_read_unlock(); | ||
1191 | err = -ENOMEM; | 1187 | err = -ENOMEM; |
1192 | goto err; | 1188 | goto err2; |
1193 | } | 1189 | } |
1194 | 1190 | ||
1195 | /* not in hash table yet so not strictly necessary */ | 1191 | /* not in hash table yet so not strictly necessary */ |
@@ -1198,44 +1194,34 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1198 | } else { | 1194 | } else { |
1199 | /* try an implicit helper assignation */ | 1195 | /* try an implicit helper assignation */ |
1200 | err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC); | 1196 | err = __nf_ct_try_assign_helper(ct, GFP_ATOMIC); |
1201 | if (err < 0) { | 1197 | if (err < 0) |
1202 | rcu_read_unlock(); | 1198 | goto err2; |
1203 | goto err; | ||
1204 | } | ||
1205 | } | 1199 | } |
1206 | 1200 | ||
1207 | if (cda[CTA_STATUS]) { | 1201 | if (cda[CTA_STATUS]) { |
1208 | err = ctnetlink_change_status(ct, cda); | 1202 | err = ctnetlink_change_status(ct, cda); |
1209 | if (err < 0) { | 1203 | if (err < 0) |
1210 | rcu_read_unlock(); | 1204 | goto err2; |
1211 | goto err; | ||
1212 | } | ||
1213 | } | 1205 | } |
1214 | 1206 | ||
1215 | if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { | 1207 | if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { |
1216 | err = ctnetlink_change_nat(ct, cda); | 1208 | err = ctnetlink_change_nat(ct, cda); |
1217 | if (err < 0) { | 1209 | if (err < 0) |
1218 | rcu_read_unlock(); | 1210 | goto err2; |
1219 | goto err; | ||
1220 | } | ||
1221 | } | 1211 | } |
1222 | 1212 | ||
1223 | #ifdef CONFIG_NF_NAT_NEEDED | 1213 | #ifdef CONFIG_NF_NAT_NEEDED |
1224 | if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) { | 1214 | if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) { |
1225 | err = ctnetlink_change_nat_seq_adj(ct, cda); | 1215 | err = ctnetlink_change_nat_seq_adj(ct, cda); |
1226 | if (err < 0) { | 1216 | if (err < 0) |
1227 | rcu_read_unlock(); | 1217 | goto err2; |
1228 | goto err; | ||
1229 | } | ||
1230 | } | 1218 | } |
1231 | #endif | 1219 | #endif |
1232 | 1220 | ||
1233 | if (cda[CTA_PROTOINFO]) { | 1221 | if (cda[CTA_PROTOINFO]) { |
1234 | err = ctnetlink_change_protoinfo(ct, cda); | 1222 | err = ctnetlink_change_protoinfo(ct, cda); |
1235 | if (err < 0) { | 1223 | if (err < 0) |
1236 | rcu_read_unlock(); | 1224 | goto err2; |
1237 | goto err; | ||
1238 | } | ||
1239 | } | 1225 | } |
1240 | 1226 | ||
1241 | nf_ct_acct_ext_add(ct, GFP_ATOMIC); | 1227 | nf_ct_acct_ext_add(ct, GFP_ATOMIC); |
@@ -1253,12 +1239,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1253 | 1239 | ||
1254 | err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3); | 1240 | err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3); |
1255 | if (err < 0) | 1241 | if (err < 0) |
1256 | goto err; | 1242 | goto err2; |
1257 | 1243 | ||
1258 | master_h = __nf_conntrack_find(&init_net, &master); | 1244 | master_h = __nf_conntrack_find(&init_net, &master); |
1259 | if (master_h == NULL) { | 1245 | if (master_h == NULL) { |
1260 | err = -ENOENT; | 1246 | err = -ENOENT; |
1261 | goto err; | 1247 | goto err2; |
1262 | } | 1248 | } |
1263 | master_ct = nf_ct_tuplehash_to_ctrack(master_h); | 1249 | master_ct = nf_ct_tuplehash_to_ctrack(master_h); |
1264 | nf_conntrack_get(&master_ct->ct_general); | 1250 | nf_conntrack_get(&master_ct->ct_general); |
@@ -1271,7 +1257,10 @@ ctnetlink_create_conntrack(struct nlattr *cda[], | |||
1271 | rcu_read_unlock(); | 1257 | rcu_read_unlock(); |
1272 | 1258 | ||
1273 | return ct; | 1259 | return ct; |
1274 | err: | 1260 | |
1261 | err2: | ||
1262 | rcu_read_unlock(); | ||
1263 | err1: | ||
1275 | nf_conntrack_free(ct); | 1264 | nf_conntrack_free(ct); |
1276 | return ERR_PTR(err); | 1265 | return ERR_PTR(err); |
1277 | } | 1266 | } |