From: Namhyung Kim <namhyung@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
Kan Liang <kan.liang@linux.intel.com>,
James Clark <james.clark@linaro.org>,
Howard Chu <howardchu95@gmail.com>,
Athira Jajeev <atrajeev@linux.vnet.ibm.com>,
Michael Petlan <mpetlan@redhat.com>,
Veronika Molnarova <vmolnaro@redhat.com>,
Dapeng Mi <dapeng1.mi@linux.intel.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Colin Ian King <colin.i.king@gmail.com>,
Weilin Wang <weilin.wang@intel.com>,
Andi Kleen <ak@linux.intel.com>,
Josh Poimboeuf <jpoimboe@redhat.com>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: Re: [PATCH v6 06/22] perf script: Use openat for directory iteration
Date: Mon, 18 Nov 2024 16:25:26 -0800 [thread overview]
Message-ID: <Zzva9rJ6lHUMD0tm@google.com> (raw)
In-Reply-To: <20241109061809.811922-7-irogers@google.com>
On Fri, Nov 08, 2024 at 10:17:53PM -0800, Ian Rogers wrote:
> Rewrite the directory iteration to use openat so that large character
> arrays aren't needed. The arrays are warned about potential buffer
> overflows by GCC when the code exists in a single C file.
>
> Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Thanks for doing this!
Namhyung
> ---
> tools/perf/builtin-script.c | 87 +++++++++++++++++++++++++------------
> tools/perf/util/path.c | 10 +++++
> tools/perf/util/path.h | 1 +
> 3 files changed, 71 insertions(+), 27 deletions(-)
>
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 5d5a1a06d8c6..e20d55b8a741 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -3530,27 +3530,35 @@ static void free_dlarg(void)
> * which is covered well now. And new parsing code should be added to
> * cover the future complex formats like event groups etc.
> */
> -static int check_ev_match(char *dir_name, char *scriptname,
> - struct perf_session *session)
> +static int check_ev_match(int dir_fd, const char *scriptname, struct perf_session *session)
> {
> - char filename[MAXPATHLEN], evname[128];
> - char line[BUFSIZ], *p;
> - struct evsel *pos;
> - int match, len;
> + char line[BUFSIZ];
> FILE *fp;
>
> - scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
> + {
> + char filename[FILENAME_MAX + 5];
> + int fd;
>
> - fp = fopen(filename, "r");
> - if (!fp)
> - return -1;
> + scnprintf(filename, sizeof(filename), "bin/%s-record", scriptname);
> + fd = openat(dir_fd, filename, O_RDONLY);
> + if (fd == -1)
> + return -1;
> + fp = fdopen(fd, "r");
> + if (!fp)
> + return -1;
> + }
>
> while (fgets(line, sizeof(line), fp)) {
> - p = skip_spaces(line);
> + char *p = skip_spaces(line);
> +
> if (*p == '#')
> continue;
>
> while (strlen(p)) {
> + int match, len;
> + struct evsel *pos;
> + char evname[128];
> +
> p = strstr(p, "-e");
> if (!p)
> break;
> @@ -3593,7 +3601,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
> int pathlen)
> {
> struct dirent *script_dirent, *lang_dirent;
> - char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
> + int scripts_dir_fd, lang_dir_fd;
> DIR *scripts_dir, *lang_dir;
> struct perf_session *session;
> struct perf_data data = {
> @@ -3602,51 +3610,76 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
> };
> char *temp;
> int i = 0;
> + const char *exec_path = get_argv_exec_path();
>
> session = perf_session__new(&data, NULL);
> if (IS_ERR(session))
> return PTR_ERR(session);
>
> - snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
> + {
> + char scripts_path[PATH_MAX];
>
> - scripts_dir = opendir(scripts_path);
> + snprintf(scripts_path, sizeof(scripts_path), "%s/scripts", exec_path);
> + scripts_dir_fd = open(scripts_path, O_DIRECTORY);
> + pr_err("Failed to open directory '%s'", scripts_path);
> + if (scripts_dir_fd == -1) {
> + perf_session__delete(session);
> + return -1;
> + }
> + }
> + scripts_dir = fdopendir(scripts_dir_fd);
> if (!scripts_dir) {
> + close(scripts_dir_fd);
> perf_session__delete(session);
> return -1;
> }
>
> - for_each_lang(scripts_path, scripts_dir, lang_dirent) {
> - scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
> - lang_dirent->d_name);
> + while ((lang_dirent = readdir(scripts_dir)) != NULL) {
> + if (lang_dirent->d_type != DT_DIR &&
> + (lang_dirent->d_type == DT_UNKNOWN &&
> + !is_directory_at(scripts_dir_fd, lang_dirent->d_name)))
> + continue;
> + if (!strcmp(lang_dirent->d_name, ".") || !strcmp(lang_dirent->d_name, ".."))
> + continue;
> +
> #ifndef HAVE_LIBPERL_SUPPORT
> - if (strstr(lang_path, "perl"))
> + if (strstr(lang_dirent->d_name, "perl"))
> continue;
> #endif
> #ifndef HAVE_LIBPYTHON_SUPPORT
> - if (strstr(lang_path, "python"))
> + if (strstr(lang_dirent->d_name, "python"))
> continue;
> #endif
>
> - lang_dir = opendir(lang_path);
> - if (!lang_dir)
> + lang_dir_fd = openat(scripts_dir_fd, lang_dirent->d_name, O_DIRECTORY);
> + if (lang_dir_fd == -1)
> continue;
> -
> - for_each_script(lang_path, lang_dir, script_dirent) {
> + lang_dir = fdopendir(lang_dir_fd);
> + if (!lang_dir) {
> + close(lang_dir_fd);
> + continue;
> + }
> + while ((script_dirent = readdir(lang_dir)) != NULL) {
> + if (script_dirent->d_type == DT_DIR)
> + continue;
> + if (script_dirent->d_type == DT_UNKNOWN &&
> + is_directory_at(lang_dir_fd, script_dirent->d_name))
> + continue;
> /* Skip those real time scripts: xxxtop.p[yl] */
> if (strstr(script_dirent->d_name, "top."))
> continue;
> if (i >= num)
> break;
> - snprintf(scripts_path_array[i], pathlen, "%s/%s",
> - lang_path,
> + scnprintf(scripts_path_array[i], pathlen, "%s/scripts/%s/%s",
> + exec_path,
> + lang_dirent->d_name,
> script_dirent->d_name);
> temp = strchr(script_dirent->d_name, '.');
> snprintf(scripts_array[i],
> (temp - script_dirent->d_name) + 1,
> "%s", script_dirent->d_name);
>
> - if (check_ev_match(lang_path,
> - scripts_array[i], session))
> + if (check_ev_match(lang_dir_fd, scripts_array[i], session))
> continue;
>
> i++;
> diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c
> index 00adf872bf00..9712466c51e2 100644
> --- a/tools/perf/util/path.c
> +++ b/tools/perf/util/path.c
> @@ -68,6 +68,16 @@ bool is_directory(const char *base_path, const struct dirent *dent)
> return S_ISDIR(st.st_mode);
> }
>
> +bool is_directory_at(int dir_fd, const char *path)
> +{
> + struct stat st;
> +
> + if (fstatat(dir_fd, path, &st, /*flags=*/0))
> + return false;
> +
> + return S_ISDIR(st.st_mode);
> +}
> +
> bool is_executable_file(const char *base_path, const struct dirent *dent)
> {
> char path[PATH_MAX];
> diff --git a/tools/perf/util/path.h b/tools/perf/util/path.h
> index d94902c22222..fbafbe7015dd 100644
> --- a/tools/perf/util/path.h
> +++ b/tools/perf/util/path.h
> @@ -12,6 +12,7 @@ int path__join3(char *bf, size_t size, const char *path1, const char *path2, con
>
> bool is_regular_file(const char *file);
> bool is_directory(const char *base_path, const struct dirent *dent);
> +bool is_directory_at(int dir_fd, const char *path);
> bool is_executable_file(const char *base_path, const struct dirent *dent);
>
> #endif /* _PERF_PATH_H */
> --
> 2.47.0.277.g8800431eea-goog
>
next prev parent reply other threads:[~2024-11-19 0:25 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-09 6:17 [PATCH v6 00/22] Python module cleanup Ian Rogers
2024-11-09 6:17 ` [PATCH v6 01/22] perf python: Remove python 2 scripting support Ian Rogers
2024-11-09 6:17 ` [PATCH v6 02/22] perf python: Constify variables and parameters Ian Rogers
2024-11-09 6:17 ` [PATCH v6 03/22] perf python: Remove unused #include Ian Rogers
2024-11-09 6:17 ` [PATCH v6 04/22] perf script: Move scripting_max_stack out of builtin Ian Rogers
2024-11-09 6:17 ` [PATCH v6 05/22] perf kvm: Move functions used in util " Ian Rogers
2024-11-09 6:17 ` [PATCH v6 06/22] perf script: Use openat for directory iteration Ian Rogers
2024-11-19 0:25 ` Namhyung Kim [this message]
2024-11-09 6:17 ` [PATCH v6 07/22] perf script: Move find_scripts to browser/scripts.c Ian Rogers
2024-11-19 0:26 ` Namhyung Kim
2024-11-09 6:17 ` [PATCH v6 08/22] perf stat: Move stat_config into config.c Ian Rogers
2024-11-09 6:17 ` [PATCH v6 09/22] perf script: Move script_spec code to trace-event-scripting.c Ian Rogers
2024-11-09 6:17 ` [PATCH v6 10/22] perf script: Move script_fetch_insn " Ian Rogers
2024-11-09 6:17 ` [PATCH v6 11/22] perf script: Move perf_sample__sprintf_flags " Ian Rogers
2024-11-09 6:17 ` [PATCH v6 12/22] perf x86: Define arch_fetch_insn in NO_AUXTRACE builds Ian Rogers
2024-11-09 6:18 ` [PATCH v6 13/22] perf intel-pt: Remove stale build comment Ian Rogers
2024-11-09 6:18 ` [PATCH v6 14/22] perf env: Move arch errno function to only use in env Ian Rogers
2024-11-09 6:18 ` [PATCH v6 15/22] perf lock: Move common lock contention code to new file Ian Rogers
2024-11-19 0:23 ` Namhyung Kim
2024-11-19 1:03 ` Ian Rogers
2024-11-19 17:00 ` Namhyung Kim
2024-11-19 17:21 ` Ian Rogers
2024-11-09 6:18 ` [PATCH v6 16/22] perf bench: Remove reference to cmd_inject Ian Rogers
2024-11-09 6:18 ` [PATCH v6 17/22] perf kwork: Make perf_kwork_add_work a callback Ian Rogers
2024-11-09 6:18 ` [PATCH v6 18/22] perf build: Remove test library from python shared object Ian Rogers
2024-11-09 6:18 ` [PATCH v6 19/22] perf python: Add parse_events function Ian Rogers
2024-11-09 6:18 ` [PATCH v6 20/22] perf python: Add __str__ and __repr__ functions to evlist Ian Rogers
2024-11-09 6:18 ` [PATCH v6 21/22] perf python: Add __str__ and __repr__ functions to evsel Ian Rogers
2024-11-09 6:18 ` [PATCH v6 22/22] perf python: Correctly throw IndexError Ian Rogers
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=Zzva9rJ6lHUMD0tm@google.com \
--to=namhyung@kernel.org \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atrajeev@linux.vnet.ibm.com \
--cc=colin.i.king@gmail.com \
--cc=dapeng1.mi@linux.intel.com \
--cc=howardchu95@gmail.com \
--cc=iii@linux.ibm.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=jpoimboe@redhat.com \
--cc=kan.liang@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=mpetlan@redhat.com \
--cc=peterz@infradead.org \
--cc=tmricht@linux.ibm.com \
--cc=vmolnaro@redhat.com \
--cc=weilin.wang@intel.com \
/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;
as well as URLs for NNTP newsgroup(s).