History

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. ]

kiyin(尹亮) committed 6 years ago

Commit 7bdb1571 parent 659caaf1 file · +5 −7Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t