perf report: Fix memory leaks around perf_tip()
authorIan Rogers <irogers@google.com>
Thu, 18 Nov 2021 07:38:04 +0000 (23:38 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 18 Nov 2021 13:18:03 +0000 (10:18 -0300)
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>
tools/perf/builtin-report.c
tools/perf/util/util.c
tools/perf/util/util.h

index 8167ebfe776a790aac12ab9cb01167dd62094a2f..8ae400429870a8fc5a191b420d5711c39c86842c 100644 (file)
@@ -619,14 +619,17 @@ static int report__browse_hists(struct report *rep)
        int ret;
        struct perf_session *session = rep->session;
        struct evlist *evlist = session->evlist;
-       const char *help = perf_tip(system_path(TIPDIR));
+       char *help = NULL, *path = NULL;
 
-       if (help == NULL) {
+       path = system_path(TIPDIR);
+       if (perf_tip(&help, path) || help == NULL) {
                /* fallback for people who don't install perf ;-) */
-               help = perf_tip(DOCDIR);
-               if (help == NULL)
-                       help = "Cannot load tips.txt file, please install perf!";
+               free(path);
+               path = system_path(DOCDIR);
+               if (perf_tip(&help, path) || help == NULL)
+                       help = strdup("Cannot load tips.txt file, please install perf!");
        }
+       free(path);
 
        switch (use_browser) {
        case 1:
@@ -651,7 +654,7 @@ static int report__browse_hists(struct report *rep)
                ret = evlist__tty_browse_hists(evlist, rep, help);
                break;
        }
-
+       free(help);
        return ret;
 }
 
index 37a9492edb3ebf094e348c1ab4e72e9dfe9d2378..df3c4671be72afd5ef426ea4f3c79a5f50dc0874 100644 (file)
@@ -379,32 +379,32 @@ fetch_kernel_version(unsigned int *puint, char *str,
        return 0;
 }
 
-const char *perf_tip(const char *dirpath)
+int perf_tip(char **strp, const char *dirpath)
 {
        struct strlist *tips;
        struct str_node *node;
-       char *tip = NULL;
        struct strlist_config conf = {
                .dirname = dirpath,
                .file_only = true,
        };
+       int ret = 0;
 
+       *strp = NULL;
        tips = strlist__new("tips.txt", &conf);
        if (tips == NULL)
-               return errno == ENOENT ? NULL :
-                       "Tip: check path of tips.txt or get more memory! ;-p";
+               return -errno;
 
        if (strlist__nr_entries(tips) == 0)
                goto out;
 
        node = strlist__entry(tips, random() % strlist__nr_entries(tips));
-       if (asprintf(&tip, "Tip: %s", node->s) < 0)
-               tip = (char *)"Tip: get more memory! ;-)";
+       if (asprintf(strp, "Tip: %s", node->s) < 0)
+               ret = -ENOMEM;
 
 out:
        strlist__delete(tips);
 
-       return tip;
+       return ret;
 }
 
 char *perf_exe(char *buf, int len)
index ad737052e59776dfe122ac633e737e972c5de217..9f0d36ba77f2d1734daced16f71dd3c2c053892c 100644 (file)
@@ -39,7 +39,7 @@ int fetch_kernel_version(unsigned int *puint,
 #define KVER_FMT       "%d.%d.%d"
 #define KVER_PARAM(x)  KVER_VERSION(x), KVER_PATCHLEVEL(x), KVER_SUBLEVEL(x)
 
-const char *perf_tip(const char *dirpath);
+int perf_tip(char **strp, const char *dirpath);
 
 #ifndef HAVE_SCHED_GETCPU_SUPPORT
 int sched_getcpu(void);