Messages in this thread Patch in this message | | | From | Chen Wandun <> | Subject | [PATCH next] perf tools: fix potential memleak in perf events parser | Date | Thu, 11 Jun 2020 09:42:34 +0800 |
| |
Fix potential memory leak in function parse_events_term__sym_hw() and parse_events_term__clone().
1. Free memory when errors occur. 2. Function new_term may return error, so it is need to free memory when the return value is negative.
Signed-off-by: Chen Wandun <chenwandun@huawei.com> --- tools/perf/util/parse-events.c | 40 +++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 3decbb203846..3491c18edd71 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2947,6 +2947,7 @@ int parse_events_term__sym_hw(struct parse_events_term **term, .type_term = PARSE_EVENTS__TERM_TYPE_USER, .config = config, }; + int ret; if (!temp.config) { temp.config = strdup("event"); @@ -2957,9 +2958,20 @@ int parse_events_term__sym_hw(struct parse_events_term **term, sym = &event_symbols_hw[idx]; str = strdup(sym->symbol); - if (!str) + if (!str) { + if (!config) + free(temp.config); return -ENOMEM; - return new_term(term, &temp, str, 0); + } + + ret = new_term(term, &temp, str, 0); + if (ret < 0) { + free(str); + if (!config) + free(temp.config); + } + + return ret; } int parse_events_term__clone(struct parse_events_term **new, @@ -2973,19 +2985,35 @@ int parse_events_term__clone(struct parse_events_term **new, .err_term = term->err_term, .err_val = term->err_val, }; + int ret; if (term->config) { temp.config = strdup(term->config); if (!temp.config) return -ENOMEM; } - if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) - return new_term(new, &temp, NULL, term->val.num); + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { + ret = new_term(new, &temp, NULL, term->val.num); + if (ret < 0 && term->config) + free(temp.config); + return ret; + } str = strdup(term->val.str); - if (!str) + if (!str) { + if (term->config) + free(temp.config); return -ENOMEM; - return new_term(new, &temp, str, 0); + } + + ret = new_term(new, &temp, str, 0); + if (ret < 0) { + free(str); + if (term->config) + free(temp.config); + } + + return ret; } void parse_events_term__delete(struct parse_events_term *term) -- 2.17.1
| |