[1/2] graph: fix memory leak

Message ID 1619092340-4047-2-git-send-email-humin29@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series bugfix for graph |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

humin (Q) April 22, 2021, 11:52 a.m. UTC
  From: HongBo Zheng <zhenghongbo3@huawei.com>

Fix function 'stats_mem_populate' return without
free dynamic memory referenced by 'stats'.

Fixes: af1ae8b6a32c ("graph: implement stats")
Cc: stable@dpdk.org

Signed-off-by: HongBo Zheng <zhenghongbo3@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
---
 lib/librte_graph/graph_stats.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
  

Comments

Kiran Kumar Kokkilagadda April 23, 2021, 3:52 a.m. UTC | #1
> -----Original Message-----
> From: Min Hu (Connor) <humin29@huawei.com>
> Sent: Thursday, April 22, 2021 5:22 PM
> To: dev@dpdk.org
> Cc: ferruh.yigit@intel.com; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Kiran Kumar Kokkilagadda <kirankumark@marvell.com>
> Subject: [EXT] [PATCH 1/2] graph: fix memory leak
> 
> External Email
> 
> ----------------------------------------------------------------------
> From: HongBo Zheng <zhenghongbo3@huawei.com>
> 
> Fix function 'stats_mem_populate' return without free dynamic memory
> referenced by 'stats'.
> 
> Fixes: af1ae8b6a32c ("graph: implement stats")
> Cc: stable@dpdk.org
> 
> Signed-off-by: HongBo Zheng <zhenghongbo3@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
>  lib/librte_graph/graph_stats.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/librte_graph/graph_stats.c b/lib/librte_graph/graph_stats.c index
> 125e08d..f698bb3 100644
> --- a/lib/librte_graph/graph_stats.c
> +++ b/lib/librte_graph/graph_stats.c
> @@ -174,7 +174,7 @@ stats_mem_populate(struct rte_graph_cluster_stats
> **stats_in,
>  	cluster->stat.hz = rte_get_timer_hz();
>  	node = graph_node_id_to_ptr(graph, id);
>  	if (node == NULL)
> -		SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph
> %s",
> +		SET_ERR_JMP(ENOENT, free, "Failed to find node %s in graph
> %s",
>  			    graph_node->node->name, graph->name);
>  	cluster->nodes[cluster->nb_nodes++] = node;
> 
> @@ -183,6 +183,8 @@ stats_mem_populate(struct rte_graph_cluster_stats
> **stats_in,
>  	*stats_in = stats;
> 
>  	return 0;
> +free:
> +	free(stats);
>  err:
>  	return -rte_errno;
>  }
> --
> 2.7.4


Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
  
David Marchand May 4, 2021, 2:15 p.m. UTC | #2
On Thu, Apr 22, 2021 at 1:52 PM Min Hu (Connor) <humin29@huawei.com> wrote:
>
> From: HongBo Zheng <zhenghongbo3@huawei.com>
>
> Fix function 'stats_mem_populate' return without
> free dynamic memory referenced by 'stats'.
>
> Fixes: af1ae8b6a32c ("graph: implement stats")
> Cc: stable@dpdk.org
>
> Signed-off-by: HongBo Zheng <zhenghongbo3@huawei.com>
> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
> ---
>  lib/librte_graph/graph_stats.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/lib/librte_graph/graph_stats.c b/lib/librte_graph/graph_stats.c
> index 125e08d..f698bb3 100644
> --- a/lib/librte_graph/graph_stats.c
> +++ b/lib/librte_graph/graph_stats.c
> @@ -174,7 +174,7 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
>         cluster->stat.hz = rte_get_timer_hz();
>         node = graph_node_id_to_ptr(graph, id);
>         if (node == NULL)
> -               SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph %s",
> +               SET_ERR_JMP(ENOENT, free, "Failed to find node %s in graph %s",
>                             graph_node->node->name, graph->name);
>         cluster->nodes[cluster->nb_nodes++] = node;
>
> @@ -183,6 +183,8 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
>         *stats_in = stats;
>
>         return 0;
> +free:
> +       free(stats);
>  err:
>         return -rte_errno;
>  }

We have a double free with this change.

If realloc on stats returns the same location, but node lookup fails,
stats_in is left untouched and still points at the original stats
location.
This location is then freed in the free: label, and later is freed in
stats_mem_fini() from caller.
  
humin (Q) May 6, 2021, 7:18 a.m. UTC | #3
在 2021/5/4 22:15, David Marchand 写道:
> On Thu, Apr 22, 2021 at 1:52 PM Min Hu (Connor) <humin29@huawei.com> wrote:
>>
>> From: HongBo Zheng <zhenghongbo3@huawei.com>
>>
>> Fix function 'stats_mem_populate' return without
>> free dynamic memory referenced by 'stats'.
>>
>> Fixes: af1ae8b6a32c ("graph: implement stats")
>> Cc: stable@dpdk.org
>>
>> Signed-off-by: HongBo Zheng <zhenghongbo3@huawei.com>
>> Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
>> ---
>>   lib/librte_graph/graph_stats.c | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/librte_graph/graph_stats.c b/lib/librte_graph/graph_stats.c
>> index 125e08d..f698bb3 100644
>> --- a/lib/librte_graph/graph_stats.c
>> +++ b/lib/librte_graph/graph_stats.c
>> @@ -174,7 +174,7 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
>>          cluster->stat.hz = rte_get_timer_hz();
>>          node = graph_node_id_to_ptr(graph, id);
>>          if (node == NULL)
>> -               SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph %s",
>> +               SET_ERR_JMP(ENOENT, free, "Failed to find node %s in graph %s",
>>                              graph_node->node->name, graph->name);
>>          cluster->nodes[cluster->nb_nodes++] = node;
>>
>> @@ -183,6 +183,8 @@ stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
>>          *stats_in = stats;
>>
>>          return 0;
>> +free:
>> +       free(stats);
>>   err:
>>          return -rte_errno;
>>   }
> 
> We have a double free with this change.
> 
Hi, David, I will set "*stats_in " to NULL.
As free(NULL) will just return and will not
result bugs.
> If realloc on stats returns the same location, but node lookup fails,
> stats_in is left untouched and still points at the original stats
> location.
> This location is then freed in the free: label, and later is freed in
> stats_mem_fini() from caller.
> 
>
  

Patch

diff --git a/lib/librte_graph/graph_stats.c b/lib/librte_graph/graph_stats.c
index 125e08d..f698bb3 100644
--- a/lib/librte_graph/graph_stats.c
+++ b/lib/librte_graph/graph_stats.c
@@ -174,7 +174,7 @@  stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
 	cluster->stat.hz = rte_get_timer_hz();
 	node = graph_node_id_to_ptr(graph, id);
 	if (node == NULL)
-		SET_ERR_JMP(ENOENT, err, "Failed to find node %s in graph %s",
+		SET_ERR_JMP(ENOENT, free, "Failed to find node %s in graph %s",
 			    graph_node->node->name, graph->name);
 	cluster->nodes[cluster->nb_nodes++] = node;
 
@@ -183,6 +183,8 @@  stats_mem_populate(struct rte_graph_cluster_stats **stats_in,
 	*stats_in = stats;
 
 	return 0;
+free:
+	free(stats);
 err:
 	return -rte_errno;
 }