diff mbox series

[net-next,1/2] net: sched: fix the err path of tcf_ct_init in act_ct

Message ID 208333ca564baf0994d3af3c454dc16127c9ad09.1663946157.git.lucien.xin@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: sched: add helper support in act_ct for ovs offloading | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers fail 1 blamed authors not CCed: paulb@mellanox.com; 3 maintainers not CCed: paulb@mellanox.com edumazet@google.com pabeni@redhat.com
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 67 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Xin Long Sept. 23, 2022, 3:28 p.m. UTC
When it returns err from tcf_ct_flow_table_get(), the param tmpl should
have been freed in the cleanup. Otherwise a memory leak will occur.

While fixing this problem, this patch also makes the err path simple by
calling tcf_ct_params_free(), so that it won't cause problems when more
members are added into param and need freeing on the err path.

Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sched/act_ct.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

Comments

Paolo Abeni Sept. 27, 2022, 12:43 p.m. UTC | #1
On Fri, 2022-09-23 at 11:28 -0400, Xin Long wrote:
> When it returns err from tcf_ct_flow_table_get(), the param tmpl should
> have been freed in the cleanup. Otherwise a memory leak will occur.
> 
> While fixing this problem, this patch also makes the err path simple by
> calling tcf_ct_params_free(), so that it won't cause problems when more
> members are added into param and need freeing on the err path.
> 
> Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

I think it's better if you re-submit this patch for -net explicitly, as
it LGTM and makes sense to let it reach the affected kernel soon.

Thanks!

Paolo
Xin Long Sept. 27, 2022, 2:45 p.m. UTC | #2
On Tue, Sep 27, 2022 at 8:43 AM Paolo Abeni <pabeni@redhat.com> wrote:
>
> On Fri, 2022-09-23 at 11:28 -0400, Xin Long wrote:
> > When it returns err from tcf_ct_flow_table_get(), the param tmpl should
> > have been freed in the cleanup. Otherwise a memory leak will occur.
> >
> > While fixing this problem, this patch also makes the err path simple by
> > calling tcf_ct_params_free(), so that it won't cause problems when more
> > members are added into param and need freeing on the err path.
> >
> > Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone")
> > Signed-off-by: Xin Long <lucien.xin@gmail.com>
>
> I think it's better if you re-submit this patch for -net explicitly, as
> it LGTM and makes sense to let it reach the affected kernel soon.
If so, I will have to wait until this patch is merged on net-next,
then post the other one for net-next, right?

>
> Thanks!
>
> Paolo
>
>
Paolo Abeni Sept. 27, 2022, 4:29 p.m. UTC | #3
On Tue, 2022-09-27 at 10:45 -0400, Xin Long wrote:
> On Tue, Sep 27, 2022 at 8:43 AM Paolo Abeni <pabeni@redhat.com> wrote:
> > 
> > On Fri, 2022-09-23 at 11:28 -0400, Xin Long wrote:
> > > When it returns err from tcf_ct_flow_table_get(), the param tmpl should
> > > have been freed in the cleanup. Otherwise a memory leak will occur.
> > > 
> > > While fixing this problem, this patch also makes the err path simple by
> > > calling tcf_ct_params_free(), so that it won't cause problems when more
> > > members are added into param and need freeing on the err path.
> > > 
> > > Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone")
> > > Signed-off-by: Xin Long <lucien.xin@gmail.com>
> > 
> > I think it's better if you re-submit this patch for -net explicitly, as
> > it LGTM and makes sense to let it reach the affected kernel soon.
> If so, I will have to wait until this patch is merged on net-next,
> then post the other one for net-next, right?

Yes. Note that such merge happens once per week...

Cheers,

Paolo
diff mbox series

Patch

diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 9d19710835b0..193a460a9d7f 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -345,11 +345,9 @@  static void tcf_ct_flow_table_cleanup_work(struct work_struct *work)
 	module_put(THIS_MODULE);
 }
 
-static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
+static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft)
 {
-	struct tcf_ct_flow_table *ct_ft = params->ct_ft;
-
-	if (refcount_dec_and_test(&params->ct_ft->ref)) {
+	if (refcount_dec_and_test(&ct_ft->ref)) {
 		rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params);
 		INIT_RCU_WORK(&ct_ft->rwork, tcf_ct_flow_table_cleanup_work);
 		queue_rcu_work(act_ct_wq, &ct_ft->rwork);
@@ -832,18 +830,23 @@  static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
 	return err;
 }
 
-static void tcf_ct_params_free(struct rcu_head *head)
+static void tcf_ct_params_free(struct tcf_ct_params *params)
 {
-	struct tcf_ct_params *params = container_of(head,
-						    struct tcf_ct_params, rcu);
-
-	tcf_ct_flow_table_put(params);
-
+	if (params->ct_ft)
+		tcf_ct_flow_table_put(params->ct_ft);
 	if (params->tmpl)
 		nf_ct_put(params->tmpl);
 	kfree(params);
 }
 
+static void tcf_ct_params_free_rcu(struct rcu_head *head)
+{
+	struct tcf_ct_params *params;
+
+	params = container_of(head, struct tcf_ct_params, rcu);
+	tcf_ct_params_free(params);
+}
+
 #if IS_ENABLED(CONFIG_NF_NAT)
 /* Modelled after nf_nat_ipv[46]_fn().
  * range is only used for new, uninitialized NAT state.
@@ -1401,14 +1404,15 @@  static int tcf_ct_init(struct net *net, struct nlattr *nla,
 	if (goto_ch)
 		tcf_chain_put_by_act(goto_ch);
 	if (params)
-		call_rcu(&params->rcu, tcf_ct_params_free);
+		call_rcu(&params->rcu, tcf_ct_params_free_rcu);
 
 	return res;
 
 cleanup:
 	if (goto_ch)
 		tcf_chain_put_by_act(goto_ch);
-	kfree(params);
+	if (params)
+		tcf_ct_params_free(params);
 	tcf_idr_release(*a, bind);
 	return err;
 }
@@ -1420,7 +1424,7 @@  static void tcf_ct_cleanup(struct tc_action *a)
 
 	params = rcu_dereference_protected(c->params, 1);
 	if (params)
-		call_rcu(&params->rcu, tcf_ct_params_free);
+		call_rcu(&params->rcu, tcf_ct_params_free_rcu);
 }
 
 static int tcf_ct_dump_key_val(struct sk_buff *skb,