Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee14186f authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller
Browse files

netfilter: xt_CT: fix missing put timeout object in error path



The error path misses putting the timeout object. This patch adds
new function xt_ct_tg_timeout_put() to put the timeout object.

Reported-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ca53e440
Loading
Loading
Loading
Loading
+19 −5
Original line number Original line Diff line number Diff line
@@ -150,6 +150,17 @@ err1:
	return ret;
	return ret;
}
}


#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout)
{
	typeof(nf_ct_timeout_put_hook) timeout_put;

	timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
	if (timeout_put)
		timeout_put(timeout);
}
#endif

static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
{
{
	struct xt_ct_target_info_v1 *info = par->targinfo;
	struct xt_ct_target_info_v1 *info = par->targinfo;
@@ -158,7 +169,9 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
	struct nf_conn *ct;
	struct nf_conn *ct;
	int ret = 0;
	int ret = 0;
	u8 proto;
	u8 proto;

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
	struct ctnl_timeout *timeout;
#endif
	if (info->flags & ~XT_CT_NOTRACK)
	if (info->flags & ~XT_CT_NOTRACK)
		return -EINVAL;
		return -EINVAL;


@@ -216,7 +229,6 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
	if (info->timeout) {
	if (info->timeout) {
		typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
		typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
		struct ctnl_timeout *timeout;
		struct nf_conn_timeout *timeout_ext;
		struct nf_conn_timeout *timeout_ext;


		rcu_read_lock();
		rcu_read_lock();
@@ -245,7 +257,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
				pr_info("Timeout policy `%s' can only be "
				pr_info("Timeout policy `%s' can only be "
					"used by L3 protocol number %d\n",
					"used by L3 protocol number %d\n",
					info->timeout, timeout->l3num);
					info->timeout, timeout->l3num);
				goto err4;
				goto err5;
			}
			}
			/* Make sure the timeout policy matches any existing
			/* Make sure the timeout policy matches any existing
			 * protocol tracker, otherwise default to generic.
			 * protocol tracker, otherwise default to generic.
@@ -258,13 +270,13 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
					"used by L4 protocol number %d\n",
					"used by L4 protocol number %d\n",
					info->timeout,
					info->timeout,
					timeout->l4proto->l4proto);
					timeout->l4proto->l4proto);
				goto err4;
				goto err5;
			}
			}
			timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
			timeout_ext = nf_ct_timeout_ext_add(ct, timeout,
							    GFP_ATOMIC);
							    GFP_ATOMIC);
			if (timeout_ext == NULL) {
			if (timeout_ext == NULL) {
				ret = -ENOMEM;
				ret = -ENOMEM;
				goto err4;
				goto err5;
			}
			}
		} else {
		} else {
			ret = -ENOENT;
			ret = -ENOENT;
@@ -282,6 +294,8 @@ out:
	return 0;
	return 0;


#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
err5:
	__xt_ct_tg_timeout_put(timeout);
err4:
err4:
	rcu_read_unlock();
	rcu_read_unlock();
#endif
#endif