aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_CT.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 80c39f0f6e91..33a02b41abb4 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -218,6 +218,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
218 struct ctnl_timeout *timeout; 218 struct ctnl_timeout *timeout;
219 struct nf_conn_timeout *timeout_ext; 219 struct nf_conn_timeout *timeout_ext;
220 220
221 rcu_read_lock();
221 timeout_find_get = 222 timeout_find_get =
222 rcu_dereference(nf_ct_timeout_find_get_hook); 223 rcu_dereference(nf_ct_timeout_find_get_hook);
223 224
@@ -228,21 +229,21 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
228 ret = -EINVAL; 229 ret = -EINVAL;
229 pr_info("You cannot use inversion on " 230 pr_info("You cannot use inversion on "
230 "L4 protocol\n"); 231 "L4 protocol\n");
231 goto err3; 232 goto err4;
232 } 233 }
233 timeout = timeout_find_get(info->timeout); 234 timeout = timeout_find_get(info->timeout);
234 if (timeout == NULL) { 235 if (timeout == NULL) {
235 ret = -ENOENT; 236 ret = -ENOENT;
236 pr_info("No such timeout policy \"%s\"\n", 237 pr_info("No such timeout policy \"%s\"\n",
237 info->timeout); 238 info->timeout);
238 goto err3; 239 goto err4;
239 } 240 }
240 if (timeout->l3num != par->family) { 241 if (timeout->l3num != par->family) {
241 ret = -EINVAL; 242 ret = -EINVAL;
242 pr_info("Timeout policy `%s' can only be " 243 pr_info("Timeout policy `%s' can only be "
243 "used by L3 protocol number %d\n", 244 "used by L3 protocol number %d\n",
244 info->timeout, timeout->l3num); 245 info->timeout, timeout->l3num);
245 goto err3; 246 goto err4;
246 } 247 }
247 if (timeout->l4proto->l4proto != e->ip.proto) { 248 if (timeout->l4proto->l4proto != e->ip.proto) {
248 ret = -EINVAL; 249 ret = -EINVAL;
@@ -250,19 +251,20 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
250 "used by L4 protocol number %d\n", 251 "used by L4 protocol number %d\n",
251 info->timeout, 252 info->timeout,
252 timeout->l4proto->l4proto); 253 timeout->l4proto->l4proto);
253 goto err3; 254 goto err4;
254 } 255 }
255 timeout_ext = nf_ct_timeout_ext_add(ct, timeout, 256 timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
256 GFP_KERNEL); 257 GFP_KERNEL);
257 if (timeout_ext == NULL) { 258 if (timeout_ext == NULL) {
258 ret = -ENOMEM; 259 ret = -ENOMEM;
259 goto err3; 260 goto err4;
260 } 261 }
261 } else { 262 } else {
262 ret = -ENOENT; 263 ret = -ENOENT;
263 pr_info("Timeout policy base is empty\n"); 264 pr_info("Timeout policy base is empty\n");
264 goto err3; 265 goto err4;
265 } 266 }
267 rcu_read_unlock();
266 } 268 }
267#endif 269#endif
268 270
@@ -272,6 +274,8 @@ out:
272 info->ct = ct; 274 info->ct = ct;
273 return 0; 275 return 0;
274 276
277err4:
278 rcu_read_unlock();
275err3: 279err3:
276 nf_conntrack_free(ct); 280 nf_conntrack_free(ct);
277err2: 281err2:
@@ -313,6 +317,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
313 nf_ct_l3proto_module_put(par->family); 317 nf_ct_l3proto_module_put(par->family);
314 318
315#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 319#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
320 rcu_read_lock();
316 timeout_put = rcu_dereference(nf_ct_timeout_put_hook); 321 timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
317 322
318 if (timeout_put) { 323 if (timeout_put) {
@@ -320,6 +325,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par)
320 if (timeout_ext) 325 if (timeout_ext)
321 timeout_put(timeout_ext->timeout); 326 timeout_put(timeout_ext->timeout);
322 } 327 }
328 rcu_read_unlock();
323#endif 329#endif
324 } 330 }
325 nf_ct_put(info->ct); 331 nf_ct_put(info->ct);