net: sched: call tcf_ct_params_free to free params in tcf_ct_init
authorXin Long <lucien.xin@gmail.com>
Sun, 6 Nov 2022 20:34:16 +0000 (15:34 -0500)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 8 Nov 2022 11:15:19 +0000 (12:15 +0100)
This patch is to make 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.

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/sched/act_ct.c

index b38d91d..193a460 100644 (file)
@@ -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 @@ out_free:
        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.
@@ -1390,7 +1393,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla,
 
        err = tcf_ct_flow_table_get(net, params);
        if (err)
-               goto cleanup_params;
+               goto cleanup;
 
        spin_lock_bh(&c->tcf_lock);
        goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
@@ -1401,17 +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_params:
-       if (params->tmpl)
-               nf_ct_put(params->tmpl);
 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;
 }
@@ -1423,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,