diff options
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/xt_CT.c | 18 |
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) struct ctnl_timeout *timeout; struct nf_conn_timeout *timeout_ext; + rcu_read_lock(); timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); @@ -228,21 +229,21 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) ret = -EINVAL; pr_info("You cannot use inversion on " "L4 protocol\n"); - goto err3; + goto err4; } timeout = timeout_find_get(info->timeout); if (timeout == NULL) { ret = -ENOENT; pr_info("No such timeout policy \"%s\"\n", info->timeout); - goto err3; + goto err4; } if (timeout->l3num != par->family) { ret = -EINVAL; pr_info("Timeout policy `%s' can only be " "used by L3 protocol number %d\n", info->timeout, timeout->l3num); - goto err3; + goto err4; } if (timeout->l4proto->l4proto != e->ip.proto) { ret = -EINVAL; @@ -250,19 +251,20 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) "used by L4 protocol number %d\n", info->timeout, timeout->l4proto->l4proto); - goto err3; + goto err4; } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_KERNEL); if (timeout_ext == NULL) { ret = -ENOMEM; - goto err3; + goto err4; } } else { ret = -ENOENT; pr_info("Timeout policy base is empty\n"); - goto err3; + goto err4; } + rcu_read_unlock(); } #endif @@ -272,6 +274,8 @@ out: info->ct = ct; return 0; +err4: + rcu_read_unlock(); err3: nf_conntrack_free(ct); err2: @@ -313,6 +317,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) nf_ct_l3proto_module_put(par->family); #ifdef CONFIG_NF_CONNTRACK_TIMEOUT + rcu_read_lock(); timeout_put = rcu_dereference(nf_ct_timeout_put_hook); if (timeout_put) { @@ -320,6 +325,7 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) if (timeout_ext) timeout_put(timeout_ext->timeout); } + rcu_read_unlock(); #endif } nf_ct_put(info->ct); |