Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf report: Fix memory leaks around perf_tip()

perf_tip() may allocate memory or use a literal, this means memory
wasn't freed if allocated. Change the API so that literals aren't used.

At the same time add missing frees for system_path. These issues were
spotted using leak sanitizer.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20211118073804.2149974-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
d9fc7061 0ca1f534

+17 -14
+9 -6
tools/perf/builtin-report.c
··· 619 619 int ret; 620 620 struct perf_session *session = rep->session; 621 621 struct evlist *evlist = session->evlist; 622 - const char *help = perf_tip(system_path(TIPDIR)); 622 + char *help = NULL, *path = NULL; 623 623 624 - if (help == NULL) { 624 + path = system_path(TIPDIR); 625 + if (perf_tip(&help, path) || help == NULL) { 625 626 /* fallback for people who don't install perf ;-) */ 626 - help = perf_tip(DOCDIR); 627 - if (help == NULL) 628 - help = "Cannot load tips.txt file, please install perf!"; 627 + free(path); 628 + path = system_path(DOCDIR); 629 + if (perf_tip(&help, path) || help == NULL) 630 + help = strdup("Cannot load tips.txt file, please install perf!"); 629 631 } 632 + free(path); 630 633 631 634 switch (use_browser) { 632 635 case 1: ··· 654 651 ret = evlist__tty_browse_hists(evlist, rep, help); 655 652 break; 656 653 } 657 - 654 + free(help); 658 655 return ret; 659 656 } 660 657
+7 -7
tools/perf/util/util.c
··· 379 379 return 0; 380 380 } 381 381 382 - const char *perf_tip(const char *dirpath) 382 + int perf_tip(char **strp, const char *dirpath) 383 383 { 384 384 struct strlist *tips; 385 385 struct str_node *node; 386 - char *tip = NULL; 387 386 struct strlist_config conf = { 388 387 .dirname = dirpath, 389 388 .file_only = true, 390 389 }; 390 + int ret = 0; 391 391 392 + *strp = NULL; 392 393 tips = strlist__new("tips.txt", &conf); 393 394 if (tips == NULL) 394 - return errno == ENOENT ? NULL : 395 - "Tip: check path of tips.txt or get more memory! ;-p"; 395 + return -errno; 396 396 397 397 if (strlist__nr_entries(tips) == 0) 398 398 goto out; 399 399 400 400 node = strlist__entry(tips, random() % strlist__nr_entries(tips)); 401 - if (asprintf(&tip, "Tip: %s", node->s) < 0) 402 - tip = (char *)"Tip: get more memory! ;-)"; 401 + if (asprintf(strp, "Tip: %s", node->s) < 0) 402 + ret = -ENOMEM; 403 403 404 404 out: 405 405 strlist__delete(tips); 406 406 407 - return tip; 407 + return ret; 408 408 } 409 409 410 410 char *perf_exe(char *buf, int len)
+1 -1
tools/perf/util/util.h
··· 39 39 #define KVER_FMT "%d.%d.%d" 40 40 #define KVER_PARAM(x) KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x) 41 41 42 - const char *perf_tip(const char *dirpath); 42 + int perf_tip(char **strp, const char *dirpath); 43 43 44 44 #ifndef HAVE_SCHED_GETCPU_SUPPORT 45 45 int sched_getcpu(void);