perf/core: Fix a memory leak in perf_event_parse_addr_filter()

As shown through runtime testing, the "filename" allocation is not
always freed in perf_event_parse_addr_filter().

There are three possible ways that this could happen:

- It could be allocated twice on subsequent iterations through the loop,
- or leaked on the success path,
- or on the failure path.

Clean up the code flow to make it obvious that 'filename' is always
freed in the reallocation path and in the two return paths as well.

We rely on the fact that kfree(NULL) is NOP and filename is initialized
with NULL.

This fixes the leak. No other side effects expected.

[ Dan Carpenter: cleaned up the code flow & added a changelog. ]
[ Ingo Molnar: updated the changelog some more. ]

Fixes: 375637bc5249 ("perf/core: Introduce address range filtering")
Signed-off-by: "kiyin(尹亮)" <kiyin@tencent.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu>
Cc: Anthony Liguori <aliguori@amazon.com>
--
kernel/events/core.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

authored by kiyin(尹亮) and committed by Ingo Molnar 7bdb157c 659caaf6

+5 -7
+5 -7
kernel/events/core.c
··· 10085 if (token == IF_SRC_FILE || token == IF_SRC_FILEADDR) { 10086 int fpos = token == IF_SRC_FILE ? 2 : 1; 10087 10088 filename = match_strdup(&args[fpos]); 10089 if (!filename) { 10090 ret = -ENOMEM; ··· 10132 */ 10133 ret = -EOPNOTSUPP; 10134 if (!event->ctx->task) 10135 - goto fail_free_name; 10136 10137 /* look up the path and grab its inode */ 10138 ret = kern_path(filename, LOOKUP_FOLLOW, 10139 &filter->path); 10140 if (ret) 10141 - goto fail_free_name; 10142 - 10143 - kfree(filename); 10144 - filename = NULL; 10145 10146 ret = -EINVAL; 10147 if (!filter->path.dentry || ··· 10158 if (state != IF_STATE_ACTION) 10159 goto fail; 10160 10161 kfree(orig); 10162 10163 return 0; 10164 10165 - fail_free_name: 10166 - kfree(filename); 10167 fail: 10168 free_filters_list(filters); 10169 kfree(orig); 10170
··· 10085 if (token == IF_SRC_FILE || token == IF_SRC_FILEADDR) { 10086 int fpos = token == IF_SRC_FILE ? 2 : 1; 10087 10088 + kfree(filename); 10089 filename = match_strdup(&args[fpos]); 10090 if (!filename) { 10091 ret = -ENOMEM; ··· 10131 */ 10132 ret = -EOPNOTSUPP; 10133 if (!event->ctx->task) 10134 + goto fail; 10135 10136 /* look up the path and grab its inode */ 10137 ret = kern_path(filename, LOOKUP_FOLLOW, 10138 &filter->path); 10139 if (ret) 10140 + goto fail; 10141 10142 ret = -EINVAL; 10143 if (!filter->path.dentry || ··· 10160 if (state != IF_STATE_ACTION) 10161 goto fail; 10162 10163 + kfree(filename); 10164 kfree(orig); 10165 10166 return 0; 10167 10168 fail: 10169 + kfree(filename); 10170 free_filters_list(filters); 10171 kfree(orig); 10172