>From a7ff65f786a38c6a612eb3b65ccdf9ea4c517503 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 3 Apr 2012 14:00:18 +0200 Subject: [PATCH] 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 do that to avoid code duplication. Reported-by: Tetsuo Handa Signed-off-by: Pablo Neira Ayuso --- net/netfilter/xt_CT.c | 44 +++++++++++++++++++++++++------------------- 1 files changed, 25 insertions(+), 19 deletions(-) diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 4babb27..89126fc 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c @@ -150,6 +150,24 @@ err1: return ret; } +static void xt_ct_tg_timeout_put(struct nf_conn *ct) +{ +#ifdef CONFIG_NF_CONNTRACK_TIMEOUT + struct nf_conn_timeout *timeout_ext; + typeof(nf_ct_timeout_put_hook) timeout_put; + + rcu_read_lock(); + timeout_put = rcu_dereference(nf_ct_timeout_put_hook); + + if (timeout_put) { + timeout_ext = nf_ct_timeout_find(ct); + if (timeout_ext) + timeout_put(timeout_ext->timeout); + } + rcu_read_unlock(); +#endif +} + static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) { struct xt_ct_target_info_v1 *info = par->targinfo; @@ -245,7 +263,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) pr_info("Timeout policy `%s' can only be " "used by L3 protocol number %d\n", info->timeout, timeout->l3num); - goto err4; + goto err5; } /* Make sure the timeout policy matches any existing * protocol tracker, otherwise default to generic. @@ -258,13 +276,13 @@ 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 err4; + goto err5; } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC); if (timeout_ext == NULL) { ret = -ENOMEM; - goto err4; + goto err5; } } else { ret = -ENOENT; @@ -282,6 +300,8 @@ out: return 0; #ifdef CONFIG_NF_CONNTRACK_TIMEOUT +err5: + xt_ct_tg_timeout_put(ct); err4: rcu_read_unlock(); #endif @@ -314,28 +334,14 @@ static void xt_ct_tg_destroy_v1(const struct xt_tgdtor_param *par) struct xt_ct_target_info_v1 *info = par->targinfo; struct nf_conn *ct = info->ct; struct nf_conn_help *help; -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT - struct nf_conn_timeout *timeout_ext; - typeof(nf_ct_timeout_put_hook) timeout_put; -#endif + if (!nf_ct_is_untracked(ct)) { help = nfct_help(ct); if (help) module_put(help->helper->me); 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) { - timeout_ext = nf_ct_timeout_find(ct); - if (timeout_ext) - timeout_put(timeout_ext->timeout); - } - rcu_read_unlock(); -#endif + xt_ct_tg_timeout_put(ct); } nf_ct_put(info->ct); } -- 1.7.2.5