netfilter: xt_CT: fix refcnt leak on error path
[ Upstream commit 470acf55a021713869b9bcc967268ac90c8a0fac ] There are two cases which causes refcnt leak. 1. When nf_ct_timeout_ext_add failed in xt_ct_set_timeout, it should free the timeout refcnt. Now goto the err_put_timeout error handler instead of going ahead. 2. When the time policy is not found, we should call module_put. Otherwise, the related cthelper module cannot be removed anymore. It is easy to reproduce by typing the following command: # iptables -t raw -A OUTPUT -p tcp -j CT --helper ftp --timeout xxx Signed-off-by: Gao Feng <fgao@ikuai8.com> Signed-off-by: Liping Zhang <zlpnobody@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8f26b63a87
commit
e05ba6ea5b
1 changed files with 9 additions and 2 deletions
|
@ -168,8 +168,10 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
|
||||||
goto err_put_timeout;
|
goto err_put_timeout;
|
||||||
}
|
}
|
||||||
timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
|
timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
|
||||||
if (timeout_ext == NULL)
|
if (!timeout_ext) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto err_put_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -201,6 +203,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
||||||
struct xt_ct_target_info_v1 *info)
|
struct xt_ct_target_info_v1 *info)
|
||||||
{
|
{
|
||||||
struct nf_conntrack_zone zone;
|
struct nf_conntrack_zone zone;
|
||||||
|
struct nf_conn_help *help;
|
||||||
struct nf_conn *ct;
|
struct nf_conn *ct;
|
||||||
int ret = -EOPNOTSUPP;
|
int ret = -EOPNOTSUPP;
|
||||||
|
|
||||||
|
@ -249,7 +252,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
|
||||||
if (info->timeout[0]) {
|
if (info->timeout[0]) {
|
||||||
ret = xt_ct_set_timeout(ct, par, info->timeout);
|
ret = xt_ct_set_timeout(ct, par, info->timeout);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err3;
|
goto err4;
|
||||||
}
|
}
|
||||||
__set_bit(IPS_CONFIRMED_BIT, &ct->status);
|
__set_bit(IPS_CONFIRMED_BIT, &ct->status);
|
||||||
nf_conntrack_get(&ct->ct_general);
|
nf_conntrack_get(&ct->ct_general);
|
||||||
|
@ -257,6 +260,10 @@ out:
|
||||||
info->ct = ct;
|
info->ct = ct;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err4:
|
||||||
|
help = nfct_help(ct);
|
||||||
|
if (help)
|
||||||
|
module_put(help->helper->me);
|
||||||
err3:
|
err3:
|
||||||
nf_ct_tmpl_free(ct);
|
nf_ct_tmpl_free(ct);
|
||||||
err2:
|
err2:
|
||||||
|
|
Loading…
Add table
Reference in a new issue