linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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
> 

  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).