From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
linux-kernel@vger.kernel.org,
Adrian Hunter <adrian.hunter@intel.com>,
Ingo Molnar <mingo@redhat.com>,
Namhyung Kim <namhyung@kernel.org>, Jiri Olsa <jolsa@redhat.com>
Subject: Re: [PATCH perf/core 02/13] perf: Make perf_exec_path always returns malloc'd string
Date: Wed, 18 Nov 2015 19:23:02 -0300 [thread overview]
Message-ID: <20151118222302.GZ22729@kernel.org> (raw)
Em Wed, Nov 18, 2015 at 03:40:14PM +0900, Masami Hiramatsu escreveu:
> Since system_path() returns malloc'd string if given path is
> not an absolute path, perf_exec_path sometimes returns static
> string and sometimes returns malloc'd string depends on the
> environment variables or command options.
>
> This causes a memory leak because caller can not free the
> returned string.
>
> This fixes perf_exec_path and system_path to always return
> malloc'd string, so caller can always free it.
> /* Returns the highest-priority, location to look for perf programs. */
> -const char *perf_exec_path(void)
> +char *perf_exec_path(void)
> {
> - const char *env;
> + char *env;
>
> if (argv_exec_path)
> - return argv_exec_path;
> + return strdup(argv_exec_path);
So here you return strdup without checking if it fails
>
> env = getenv(EXEC_PATH_ENVIRONMENT);
> if (env && *env) {
> - return env;
> + env = strdup(env);
> + if (env)
> + return env;
But here you change the behaviour by, having a EXEC_PATH_ENVIRONMENT,
fallback to PERF_EXEC_PATH if strdup fails, that in turn can end up
returning NULL, since system_path() doesn't check the strdup() result?
I wonder if in those cases we couldn't check the address range for the
pointer being freed and realize it is in .bss, .data or that it is a
stack variable? Maybe there is some malloc() friend that, given a
pointer, tells that yeah, it was allocated?
- Arnaldo
> }
>
> return system_path(PERF_EXEC_PATH);
> @@ -83,9 +85,11 @@ void setup_path(void)
> {
> const char *old_path = getenv("PATH");
> struct strbuf new_path = STRBUF_INIT;
> + char *tmp = perf_exec_path();
>
> - add_path(&new_path, perf_exec_path());
> + add_path(&new_path, tmp);
> add_path(&new_path, argv0_path);
> + free(tmp);
>
> if (old_path)
> strbuf_addstr(&new_path, old_path);
> diff --git a/tools/perf/util/exec_cmd.h b/tools/perf/util/exec_cmd.h
> index bc4b915..48b4175 100644
> --- a/tools/perf/util/exec_cmd.h
> +++ b/tools/perf/util/exec_cmd.h
> @@ -3,10 +3,11 @@
>
> extern void perf_set_argv_exec_path(const char *exec_path);
> extern const char *perf_extract_argv0_path(const char *path);
> -extern const char *perf_exec_path(void);
> extern void setup_path(void);
> extern int execv_perf_cmd(const char **argv); /* NULL terminated */
> extern int execl_perf_cmd(const char *cmd, ...);
> -extern const char *system_path(const char *path);
> +/* perf_exec_path and system_path return malloc'd string, caller must free it */
> +extern char *perf_exec_path(void);
> +extern char *system_path(const char *path);
>
> #endif /* __PERF_EXEC_CMD_H */
> diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c
> index 86c37c4..fa1fc4a 100644
> --- a/tools/perf/util/help.c
> +++ b/tools/perf/util/help.c
> @@ -159,7 +159,7 @@ void load_command_list(const char *prefix,
> struct cmdnames *other_cmds)
> {
> const char *env_path = getenv("PATH");
> - const char *exec_path = perf_exec_path();
> + char *exec_path = perf_exec_path();
>
> if (exec_path) {
> list_commands_in_dir(main_cmds, exec_path, prefix);
> @@ -187,6 +187,7 @@ void load_command_list(const char *prefix,
> sizeof(*other_cmds->names), cmdname_compare);
> uniq(other_cmds);
> }
> + free(exec_path);
> exclude_cmds(other_cmds, main_cmds);
> }
>
> @@ -203,13 +204,14 @@ void list_commands(const char *title, struct cmdnames *main_cmds,
> longest = other_cmds->names[i]->len;
>
> if (main_cmds->cnt) {
> - const char *exec_path = perf_exec_path();
> + char *exec_path = perf_exec_path();
> printf("available %s in '%s'\n", title, exec_path);
> printf("----------------");
> mput_char('-', strlen(title) + strlen(exec_path));
> putchar('\n');
> pretty_print_string_list(main_cmds, longest);
> putchar('\n');
> + free(exec_path);
> }
>
> if (other_cmds->cnt) {
----- End forwarded message -----
next reply other threads:[~2015-11-18 22:23 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-18 22:23 Arnaldo Carvalho de Melo [this message]
2015-11-19 3:46 ` 平松雅巳 / HIRAMATU,MASAMI
2015-11-19 6:04 ` [PATCH perf/core v2] " Masami Hiramatsu
2015-11-23 16:11 ` [tip:perf/core] perf tools: Make perf_exec_path() always return " tip-bot for Masami Hiramatsu
-- strict thread matches above, loose matches on Subject: below --
2015-11-18 6:40 [PATCH perf/core 00/13] perf memory/refcnt leak fixes Masami Hiramatsu
2015-11-18 6:40 ` [PATCH perf/core 02/13] perf: Make perf_exec_path always returns malloc'd string Masami Hiramatsu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151118222302.GZ22729@kernel.org \
--to=acme@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=adrian.hunter@intel.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome