diff mbox series

perf pmu: Replace all non-returning strlcpy with strscpy

Message ID 20230516000500.3884588-1-azeemshaikh38@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series perf pmu: Replace all non-returning strlcpy with strscpy | expand

Commit Message

Azeem Shaikh May 16, 2023, 12:05 a.m. UTC
strlcpy() reads the entire source buffer first.
This read may exceed the destination size limit.
This is both inefficient and can lead to linear read
overflows if a source string is not NUL-terminated [1].
In an effort to remove strlcpy() completely [2], replace
strlcpy() here with strscpy().
No return values were used, so direct replacement is safe.

[1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy
[2] https://github.com/KSPP/linux/issues/89

Signed-off-by: Azeem Shaikh <azeemshaikh38@gmail.com>
---
 kernel/events/core.c                                |    6 +++---
 tools/perf/arch/x86/util/event.c                    |    2 +-
 tools/perf/arch/x86/util/machine.c                  |    2 +-
 tools/perf/builtin-buildid-cache.c                  |    6 +++---
 tools/perf/builtin-daemon.c                         |    4 ++--
 tools/perf/jvmti/libjvmti.c                         |    2 +-
 tools/perf/tests/dlfilter-test.c                    |    2 +-
 tools/perf/tests/symbols.c                          |    2 +-
 tools/perf/ui/tui/helpline.c                        |    2 +-
 tools/perf/util/annotate.c                          |    4 ++--
 tools/perf/util/auxtrace.c                          |    2 +-
 tools/perf/util/dso.c                               |    2 +-
 tools/perf/util/intel-pt-decoder/intel-pt-decoder.c |    2 +-
 tools/perf/util/llvm-utils.c                        |    4 ++--
 tools/perf/util/machine.c                           |    8 ++++----
 tools/perf/util/pmu-hybrid.c                        |    2 +-
 tools/perf/util/pmu.c                               |    2 +-
 tools/perf/util/probe-file.c                        |    2 +-
 tools/perf/util/svghelper.c                         |    2 +-
 tools/perf/util/symbol.c                            |    4 ++--
 tools/perf/util/synthetic-events.c                  |    4 ++--
 21 files changed, 33 insertions(+), 33 deletions(-)

Comments

Kees Cook May 16, 2023, 6:14 p.m. UTC | #1
On Tue, May 16, 2023 at 12:05:00AM +0000, Azeem Shaikh wrote:
> strlcpy() reads the entire source buffer first.
> This read may exceed the destination size limit.
> This is both inefficient and can lead to linear read
> overflows if a source string is not NUL-terminated [1].
> In an effort to remove strlcpy() completely [2], replace
> strlcpy() here with strscpy().
> No return values were used, so direct replacement is safe.
> 
> [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy
> [2] https://github.com/KSPP/linux/issues/89
> 
> Signed-off-by: Azeem Shaikh <azeemshaikh38@gmail.com>

Reviewed-by: Kees Cook <keescook@chromium.org>
Arnaldo Carvalho de Melo May 17, 2023, 1:20 p.m. UTC | #2
Em Tue, May 16, 2023 at 12:05:00AM +0000, Azeem Shaikh escreveu:
> strlcpy() reads the entire source buffer first.
> This read may exceed the destination size limit.
> This is both inefficient and can lead to linear read
> overflows if a source string is not NUL-terminated [1].
> In an effort to remove strlcpy() completely [2], replace
> strlcpy() here with strscpy().
> No return values were used, so direct replacement is safe.

Peter, I'll try and process the tools/ part, to check if this builds
with all the test containers I have.

- Arnaldo
 
> [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy
> [2] https://github.com/KSPP/linux/issues/89
> 
> Signed-off-by: Azeem Shaikh <azeemshaikh38@gmail.com>
> ---
>  kernel/events/core.c                                |    6 +++---
>  tools/perf/arch/x86/util/event.c                    |    2 +-
>  tools/perf/arch/x86/util/machine.c                  |    2 +-
>  tools/perf/builtin-buildid-cache.c                  |    6 +++---
>  tools/perf/builtin-daemon.c                         |    4 ++--
>  tools/perf/jvmti/libjvmti.c                         |    2 +-
>  tools/perf/tests/dlfilter-test.c                    |    2 +-
>  tools/perf/tests/symbols.c                          |    2 +-
>  tools/perf/ui/tui/helpline.c                        |    2 +-
>  tools/perf/util/annotate.c                          |    4 ++--
>  tools/perf/util/auxtrace.c                          |    2 +-
>  tools/perf/util/dso.c                               |    2 +-
>  tools/perf/util/intel-pt-decoder/intel-pt-decoder.c |    2 +-
>  tools/perf/util/llvm-utils.c                        |    4 ++--
>  tools/perf/util/machine.c                           |    8 ++++----
>  tools/perf/util/pmu-hybrid.c                        |    2 +-
>  tools/perf/util/pmu.c                               |    2 +-
>  tools/perf/util/probe-file.c                        |    2 +-
>  tools/perf/util/svghelper.c                         |    2 +-
>  tools/perf/util/symbol.c                            |    4 ++--
>  tools/perf/util/synthetic-events.c                  |    4 ++--
>  21 files changed, 33 insertions(+), 33 deletions(-)
> 
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index db016e418931..6039fdf00b3c 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -8245,7 +8245,7 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
>  	unsigned int size;
>  
>  	memset(comm, 0, sizeof(comm));
> -	strlcpy(comm, comm_event->task->comm, sizeof(comm));
> +	strscpy(comm, comm_event->task->comm, sizeof(comm));
>  	size = ALIGN(strlen(comm)+1, sizeof(u64));
>  
>  	comm_event->comm = comm;
> @@ -8700,7 +8700,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
>  	}
>  
>  cpy_name:
> -	strlcpy(tmp, name, sizeof(tmp));
> +	strscpy(tmp, name, sizeof(tmp));
>  	name = tmp;
>  got_name:
>  	/*
> @@ -9124,7 +9124,7 @@ void perf_event_ksymbol(u16 ksym_type, u64 addr, u32 len, bool unregister,
>  	    ksym_type == PERF_RECORD_KSYMBOL_TYPE_UNKNOWN)
>  		goto err;
>  
> -	strlcpy(name, sym, KSYM_NAME_LEN);
> +	strscpy(name, sym, KSYM_NAME_LEN);
>  	name_len = strlen(name) + 1;
>  	while (!IS_ALIGNED(name_len, sizeof(u64)))
>  		name[name_len++] = '\0';
> diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c
> index 5741ffe47312..91fe2ef920c7 100644
> --- a/tools/perf/arch/x86/util/event.c
> +++ b/tools/perf/arch/x86/util/event.c
> @@ -64,7 +64,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool,
>  		event->mmap.pgoff = map__pgoff(map);
>  		event->mmap.pid   = machine->pid;
>  
> -		strlcpy(event->mmap.filename, kmap->name, PATH_MAX);
> +		strscpy(event->mmap.filename, kmap->name, PATH_MAX);
>  
>  		if (perf_tool__process_synth_event(tool, event, machine,
>  						   process) != 0) {
> diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c
> index 31679c35d493..1ff0be147205 100644
> --- a/tools/perf/arch/x86/util/machine.c
> +++ b/tools/perf/arch/x86/util/machine.c
> @@ -40,7 +40,7 @@ static int add_extra_kernel_map(struct extra_kernel_map_info *mi, u64 start,
>  	mi->maps[mi->cnt].start = start;
>  	mi->maps[mi->cnt].end   = end;
>  	mi->maps[mi->cnt].pgoff = pgoff;
> -	strlcpy(mi->maps[mi->cnt].name, name, KMAP_NAME_LEN);
> +	strscpy(mi->maps[mi->cnt].name, name, KMAP_NAME_LEN);
>  
>  	mi->cnt += 1;
>  
> diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
> index cd381693658b..0cc4c39558ad 100644
> --- a/tools/perf/builtin-buildid-cache.c
> +++ b/tools/perf/builtin-buildid-cache.c
> @@ -36,7 +36,7 @@ static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
>  	char root_dir[PATH_MAX];
>  	char *p;
>  
> -	strlcpy(root_dir, proc_dir, sizeof(root_dir));
> +	strscpy(root_dir, proc_dir, sizeof(root_dir));
>  
>  	p = strrchr(root_dir, '/');
>  	if (!p)
> @@ -104,7 +104,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
>  			  to_dir, dent->d_name);
>  		if (!compare_proc_modules(from, to) &&
>  		    same_kallsyms_reloc(from_dir, to_subdir)) {
> -			strlcpy(to_dir, to_subdir, to_dir_sz);
> +			strscpy(to_dir, to_subdir, to_dir_sz);
>  			ret = 0;
>  			break;
>  		}
> @@ -121,7 +121,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force)
>  	char from_dir[PATH_MAX], to_dir[PATH_MAX];
>  	char *p;
>  
> -	strlcpy(from_dir, filename, sizeof(from_dir));
> +	strscpy(from_dir, filename, sizeof(from_dir));
>  
>  	p = strrchr(from_dir, '/');
>  	if (!p || strcmp(p + 1, "kcore"))
> diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c
> index 34cbe3e959aa..aa6ebf46370a 100644
> --- a/tools/perf/builtin-daemon.c
> +++ b/tools/perf/builtin-daemon.c
> @@ -606,7 +606,7 @@ static int setup_server_socket(struct daemon *daemon)
>  	memset(&addr, 0, sizeof(addr));
>  	addr.sun_family = AF_UNIX;
>  
> -	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
> +	strscpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
>  	unlink(path);
>  
>  	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
> @@ -877,7 +877,7 @@ static int setup_client_socket(struct daemon *daemon)
>  
>  	memset(&addr, 0, sizeof(addr));
>  	addr.sun_family = AF_UNIX;
> -	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
> +	strscpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
>  
>  	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
>  		perror("failed: connect");
> diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c
> index fcca275e5bf9..04d6825d23c8 100644
> --- a/tools/perf/jvmti/libjvmti.c
> +++ b/tools/perf/jvmti/libjvmti.c
> @@ -158,7 +158,7 @@ copy_class_filename(const char * class_sign, const char * file_name, char * resu
>  		result[i] = '\0';
>  	} else {
>  		/* fallback case */
> -		strlcpy(result, file_name, max_length);
> +		strscpy(result, file_name, max_length);
>  	}
>  }
>  
> diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c
> index 086fd2179e41..7003418614ef 100644
> --- a/tools/perf/tests/dlfilter-test.c
> +++ b/tools/perf/tests/dlfilter-test.c
> @@ -234,7 +234,7 @@ static int get_dlfilters_path(char *buf, size_t sz)
>  		if (access(path, R_OK))
>  			return -1;
>  	}
> -	strlcpy(buf, dirname(path), sz);
> +	strscpy(buf, dirname(path), sz);
>  	return 0;
>  }
>  
> diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c
> index 2d1aa42d36a9..a6b44fa4ec6f 100644
> --- a/tools/perf/tests/symbols.c
> +++ b/tools/perf/tests/symbols.c
> @@ -45,7 +45,7 @@ static void exit_test_info(struct test_info *ti)
>  static void get_test_dso_filename(char *filename, size_t max_sz)
>  {
>  	if (dso_to_test)
> -		strlcpy(filename, dso_to_test, max_sz);
> +		strscpy(filename, dso_to_test, max_sz);
>  	else
>  		perf_exe(filename, max_sz);
>  }
> diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
> index db4952f5990b..1040e4c33469 100644
> --- a/tools/perf/ui/tui/helpline.c
> +++ b/tools/perf/ui/tui/helpline.c
> @@ -24,7 +24,7 @@ static void tui_helpline__push(const char *msg)
>  	SLsmg_set_color(0);
>  	SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols);
>  	SLsmg_refresh();
> -	strlcpy(ui_helpline__current, msg, sz);
> +	strscpy(ui_helpline__current, msg, sz);
>  }
>  
>  static int tui_helpline__show(const char *format, va_list ap)
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index 11992cfe271c..5e1a623be915 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -1702,7 +1702,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
>  		if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) {
>  			char *new_name = dso__filename_with_chroot(dso, filename);
>  			if (new_name) {
> -				strlcpy(filename, new_name, filename_size);
> +				strscpy(filename, new_name, filename_size);
>  				free(new_name);
>  			}
>  		}
> @@ -2002,7 +2002,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
>  		kce.len = sym->end - sym->start;
>  		if (!kcore_extract__create(&kce)) {
>  			delete_extract = true;
> -			strlcpy(symfs_filename, kce.extract_filename,
> +			strscpy(symfs_filename, kce.extract_filename,
>  				sizeof(symfs_filename));
>  		}
>  	} else if (dso__needs_decompress(dso)) {
> diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
> index a0368202a746..e69841ba3014 100644
> --- a/tools/perf/util/auxtrace.c
> +++ b/tools/perf/util/auxtrace.c
> @@ -1213,7 +1213,7 @@ void auxtrace_synth_guest_error(struct perf_record_auxtrace_error *auxtrace_erro
>  	auxtrace_error->fmt = 1;
>  	auxtrace_error->ip = ip;
>  	auxtrace_error->time = timestamp;
> -	strlcpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
> +	strscpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
>  	if (machine_pid) {
>  		auxtrace_error->fmt = 2;
>  		auxtrace_error->machine_pid = machine_pid;
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index a86614599269..7db2f30f6a0d 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -318,7 +318,7 @@ int filename__decompress(const char *name, char *pathname,
>  		unlink(tmpbuf);
>  
>  	if (pathname && (fd >= 0))
> -		strlcpy(pathname, tmpbuf, len);
> +		strscpy(pathname, tmpbuf, len);
>  
>  	return fd;
>  }
> diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> index b450178e3420..5b14c6701ecb 100644
> --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
> @@ -507,7 +507,7 @@ int intel_pt__strerror(int code, char *buf, size_t buflen)
>  {
>  	if (code < 1 || code >= INTEL_PT_ERR_MAX)
>  		code = INTEL_PT_ERR_UNK;
> -	strlcpy(buf, intel_pt_err_msgs[code], buflen);
> +	strscpy(buf, intel_pt_err_msgs[code], buflen);
>  	return 0;
>  }
>  
> diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
> index 4e8e243a6e4b..3d7c614adc80 100644
> --- a/tools/perf/util/llvm-utils.c
> +++ b/tools/perf/util/llvm-utils.c
> @@ -80,7 +80,7 @@ search_program(const char *def, const char *name,
>  	if (def && def[0] != '\0') {
>  		if (def[0] == '/') {
>  			if (access(def, F_OK) == 0) {
> -				strlcpy(output, def, PATH_MAX);
> +				strscpy(output, def, PATH_MAX);
>  				return 0;
>  			}
>  		} else if (def[0] != '\0')
> @@ -99,7 +99,7 @@ search_program(const char *def, const char *name,
>  	while (path) {
>  		scnprintf(buf, sizeof(buf), "%s/%s", path, name);
>  		if (access(buf, F_OK) == 0) {
> -			strlcpy(output, buf, PATH_MAX);
> +			strscpy(output, buf, PATH_MAX);
>  			ret = 0;
>  			break;
>  		}
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index 9e02e19c1b7a..d035b35d226e 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -1223,7 +1223,7 @@ int machine__create_extra_kernel_map(struct machine *machine,
>  
>  	kmap = map__kmap(map);
>  
> -	strlcpy(kmap->name, xm->name, KMAP_NAME_LEN);
> +	strscpy(kmap->name, xm->name, KMAP_NAME_LEN);
>  
>  	err = maps__insert(machine__kernel_maps(machine), map);
>  
> @@ -1314,7 +1314,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
>  			.pgoff = pgoff,
>  		};
>  
> -		strlcpy(xm.name, ENTRY_TRAMPOLINE_NAME, KMAP_NAME_LEN);
> +		strscpy(xm.name, ENTRY_TRAMPOLINE_NAME, KMAP_NAME_LEN);
>  
>  		if (machine__create_extra_kernel_map(machine, kernel, &xm) < 0)
>  			return -1;
> @@ -1935,7 +1935,7 @@ int machine__process_mmap2_event(struct machine *machine,
>  			.pgoff = event->mmap2.pgoff,
>  		};
>  
> -		strlcpy(xm.name, event->mmap2.filename, KMAP_NAME_LEN);
> +		strscpy(xm.name, event->mmap2.filename, KMAP_NAME_LEN);
>  		ret = machine__process_kernel_mmap_event(machine, &xm, bid);
>  		if (ret < 0)
>  			goto out_problem;
> @@ -1992,7 +1992,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event
>  			.pgoff = event->mmap.pgoff,
>  		};
>  
> -		strlcpy(xm.name, event->mmap.filename, KMAP_NAME_LEN);
> +		strscpy(xm.name, event->mmap.filename, KMAP_NAME_LEN);
>  		ret = machine__process_kernel_mmap_event(machine, &xm, NULL);
>  		if (ret < 0)
>  			goto out_problem;
> diff --git a/tools/perf/util/pmu-hybrid.c b/tools/perf/util/pmu-hybrid.c
> index 38628805a952..1c6e7f7da856 100644
> --- a/tools/perf/util/pmu-hybrid.c
> +++ b/tools/perf/util/pmu-hybrid.c
> @@ -27,7 +27,7 @@ bool perf_pmu__hybrid_mounted(const char *name)
>  	if (strncmp(name, "cpu_", 4))
>  		return false;
>  
> -	strlcpy(pmu_name, name, sizeof(pmu_name));
> +	strscpy(pmu_name, name, sizeof(pmu_name));
>  	return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0;
>  }
>  
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index ad209c88a124..7e2d97926e9f 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -599,7 +599,7 @@ static struct perf_cpu_map *pmu_cpumask(int dirfd, const char *name)
>  	struct perf_pmu pmu = {.name = pmu_name};
>  	FILE *file;
>  
> -	strlcpy(pmu_name, name, sizeof(pmu_name));
> +	strscpy(pmu_name, name, sizeof(pmu_name));
>  	for (template = templates; *template; template++) {
>  		file = perf_pmu__open_file_at(&pmu, dirfd, *template);
>  		if (!file)
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index 3d50de3217d5..8bc90b856ce3 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -459,7 +459,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target,
>  
>  	if (target && build_id_cache__cached(target)) {
>  		/* This is a cached buildid */
> -		strlcpy(sbuildid, target, SBUILD_ID_SIZE);
> +		strscpy(sbuildid, target, SBUILD_ID_SIZE);
>  		dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
>  		goto found;
>  	}
> diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
> index 5c62d3118c41..dd877b259f75 100644
> --- a/tools/perf/util/svghelper.c
> +++ b/tools/perf/util/svghelper.c
> @@ -332,7 +332,7 @@ static char *cpu_model(void)
>  	if (file) {
>  		while (fgets(buf, 255, file)) {
>  			if (strstr(buf, "model name")) {
> -				strlcpy(cpu_m, &buf[13], 255);
> +				strscpy(cpu_m, &buf[13], 255);
>  				break;
>  			}
>  		}
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 6b9c55784b56..57223c770b89 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -1967,7 +1967,7 @@ int dso__load(struct dso *dso, struct map *map)
>  			char *new_name = dso__filename_with_chroot(dso, name);
>  			if (new_name) {
>  				is_reg = is_regular_file(new_name);
> -				strlcpy(name, new_name, PATH_MAX);
> +				strscpy(name, new_name, PATH_MAX);
>  				free(new_name);
>  			}
>  		}
> @@ -2254,7 +2254,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
>  		scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
>  			  "%s/%s/kallsyms", dir, nd->s);
>  		if (!validate_kcore_addresses(kallsyms_filename, map)) {
> -			strlcpy(dir, kallsyms_filename, dir_sz);
> +			strscpy(dir, kallsyms_filename, dir_sz);
>  			ret = 0;
>  			break;
>  		}
> diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
> index b2e4afa5efa1..d7c13e3ded9f 100644
> --- a/tools/perf/util/synthetic-events.c
> +++ b/tools/perf/util/synthetic-events.c
> @@ -1979,7 +1979,7 @@ int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evse
>  	if (ev == NULL)
>  		return -ENOMEM;
>  
> -	strlcpy(ev->unit, evsel->unit, size + 1);
> +	strscpy(ev->unit, evsel->unit, size + 1);
>  	err = process(tool, (union perf_event *)ev, NULL, NULL);
>  	free(ev);
>  	return err;
> @@ -2013,7 +2013,7 @@ int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evse
>  	if (ev == NULL)
>  		return -ENOMEM;
>  
> -	strlcpy(ev->name, evsel->name, len + 1);
> +	strscpy(ev->name, evsel->name, len + 1);
>  	err = process(tool, (union perf_event *)ev, NULL, NULL);
>  	free(ev);
>  	return err;
> -- 
> 2.40.1.606.ga4b1b128d6-goog
> 
>
Arnaldo Carvalho de Melo May 17, 2023, 1:25 p.m. UTC | #3
Em Tue, May 16, 2023 at 11:14:38AM -0700, Kees Cook escreveu:
> On Tue, May 16, 2023 at 12:05:00AM +0000, Azeem Shaikh wrote:
> > strlcpy() reads the entire source buffer first.
> > This read may exceed the destination size limit.
> > This is both inefficient and can lead to linear read
> > overflows if a source string is not NUL-terminated [1].
> > In an effort to remove strlcpy() completely [2], replace
> > strlcpy() here with strscpy().
> > No return values were used, so direct replacement is safe.
> > 
> > [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy
> > [2] https://github.com/KSPP/linux/issues/89
> > 
> > Signed-off-by: Azeem Shaikh <azeemshaikh38@gmail.com>
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>

Not building as strscpy() doesn't seem to be available for tools/ code,
probably you'll need to first copy from the kernel too tools/lib/.

- Arnaldo

  CLANG   /tmp/build/perf-tools-next/util/bpf_skel/.tmp/sample_filter.bpf.o
jvmti/libjvmti.c: In function ‘copy_class_filename’:
jvmti/libjvmti.c:161:17: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
  161 |                 strscpy(result, file_name, max_length);
      |                 ^~~~~~~
      |                 strlcpy
cc1: all warnings being treated as errors
make[3]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/jvmti/libjvmti.o] Error 1
make[2]: *** [Makefile.perf:818: /tmp/build/perf-tools-next/jvmti/jvmti-in.o] Error 2
make[2]: *** Waiting for unfinished jobs....
/var/home/acme/git/perf-tools-next/tools/perf/util/pmu-hybrid.c: In function ‘perf_pmu__hybrid_mounted’:
/var/home/acme/git/perf-tools-next/tools/perf/util/pmu-hybrid.c:30:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
   30 |         strscpy(pmu_name, name, sizeof(pmu_name));
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
error: command '/usr/lib64/ccache/gcc' failed with exit code 1
cp: cannot stat '/tmp/build/perf-tools-next/python_ext_build/lib/perf*.so': No such file or directory
make[2]: *** [Makefile.perf:651: /tmp/build/perf-tools-next/python/perf.cpython-311-x86_64-linux-gnu.so] Error 1

Auto-detecting system features:
...                         clang-bpf-co-re: [ on  ]
...                                    llvm: [ OFF ]
...                                  libcap: [ on  ]
...                                  libbfd: [ on  ]

  MKDIR   /tmp/build/perf-tools-next/util/bpf_skel/.tmp/bootstrap/libbpf/include/bpf
  MKDIR   /tmp/build/perf-tools-next/util/bpf_skel/.tmp/bootstrap/

  CC      /tmp/build/perf-tools-next/util/intel-pt-decoder/intel-pt-log.o
util/llvm-utils.c: In function ‘search_program’:
util/llvm-utils.c:83:33: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
   83 |                                 strscpy(output, def, PATH_MAX);
      |                                 ^~~~~~~
      |                                 strlcpy
cc1: all warnings being treated as errors
  CC      /tmp/build/perf-tools-next/util/intel-pt-decoder/intel-pt-decoder.o
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:98: /tmp/build/perf-tools-next/util/llvm-utils.o] Error 1
make[4]: *** Waiting for unfinished jobs....
  CC      /tmp/build/perf-tools-next/util/cs-etm-base.o
  CC      /tmp/build/perf-tools-next/util/parse-branch-options.o
  LD      /tmp/build/perf-tools-next/util/cs-etm-decoder/perf-in.o
  LD      /tmp/build/perf-tools-next/util/hisi-ptt-decoder/perf-in.o
  LD      /tmp/build/perf-tools-next/util/arm-spe-decoder/perf-in.o
  CC      /tmp/build/perf-tools-next/util/intel-pt-decoder/intel-pt-insn-decoder.o
  LD      /tmp/build/perf-tools-next/util/scripting-engines/perf-in.o
util/pmu-hybrid.c: In function ‘perf_pmu__hybrid_mounted’:
util/pmu-hybrid.c:30:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
   30 |         strscpy(pmu_name, name, sizeof(pmu_name));
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/pmu-hybrid.o] Error 1
tests/symbols.c: In function ‘get_test_dso_filename’:
tests/symbols.c:48:17: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
   48 |                 strscpy(filename, dso_to_test, max_sz);
      |                 ^~~~~~~
      |                 strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/tests/symbols.o] Error 1
make[4]: *** Waiting for unfinished jobs....
tests/dlfilter-test.c: In function ‘get_dlfilters_path’:
tests/dlfilter-test.c:237:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
  237 |         strscpy(buf, dirname(path), sz);
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/tests/dlfilter-test.o] Error 1
make[3]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:140: tests] Error 2
/var/home/acme/git/perf-tools-next/tools/perf/util/pmu-hybrid.c: In function ‘perf_pmu__hybrid_mounted’:
/var/home/acme/git/perf-tools-next/tools/perf/util/pmu-hybrid.c:30:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
   30 |         strscpy(pmu_name, name, sizeof(pmu_name));
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
error: command '/usr/lib64/ccache/gcc' failed with exit code 1
cp: cannot stat '/tmp/build/perf-tools-next/python_ext_build/lib/perf*.so': No such file or directory
make[2]: *** [Makefile.perf:651: /tmp/build/perf-tools-next/python/perf.cpython-311-x86_64-linux-gnu.so] Error 1
util/svghelper.c: In function ‘cpu_model’:
util/svghelper.c:335:33: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
  335 |                                 strscpy(cpu_m, &buf[13], 255);
      |                                 ^~~~~~~
      |                                 strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/svghelper.o] Error 1
util/dso.c: In function ‘filename__decompress’:
util/dso.c:354:17: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
  354 |                 strscpy(pathname, tmpbuf, len);
      |                 ^~~~~~~
      |                 strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/dso.o] Error 1
util/symbol.c: In function ‘dso__load’:
util/symbol.c:1970:33: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
 1970 |                                 strscpy(name, new_name, PATH_MAX);
      |                                 ^~~~~~~
      |                                 strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/symbol.o] Error 1
util/annotate.c: In function ‘dso__disassemble_filename’:
util/annotate.c:1718:33: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
 1718 |                                 strscpy(filename, new_name, filename_size);
      |                                 ^~~~~~~
      |                                 strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/annotate.o] Error 1
util/synthetic-events.c: In function ‘perf_event__synthesize_event_update_unit’:
util/synthetic-events.c:1982:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
 1982 |         strscpy(ev->unit, evsel->unit, size + 1);
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/synthetic-events.o] Error 1
util/auxtrace.c: In function ‘auxtrace_synth_guest_error’:
util/auxtrace.c:1216:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
 1216 |         strscpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/auxtrace.o] Error 1
util/intel-pt-decoder/intel-pt-decoder.c: In function ‘intel_pt__strerror’:
util/intel-pt-decoder/intel-pt-decoder.c:510:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
  510 |         strscpy(buf, intel_pt_err_msgs[code], buflen);
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[5]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/intel-pt-decoder/intel-pt-decoder.o] Error 1
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:140: intel-pt-decoder] Error 2
util/machine.c: In function ‘machine__create_extra_kernel_map’:
util/machine.c:1226:9: error: implicit declaration of function ‘strscpy’; did you mean ‘strlcpy’? [-Werror=implicit-function-declaration]
 1226 |         strscpy(kmap->name, xm->name, KMAP_NAME_LEN);
      |         ^~~~~~~
      |         strlcpy
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:97: /tmp/build/perf-tools-next/util/machine.o] Error 1
make[3]: *** [/var/home/acme/git/perf-tools-next/tools/build/Makefile.build:140: util] Error 2
make[2]: *** [Makefile.perf:676: /tmp/build/perf-tools-next/perf-in.o] Error 2
  CC      /tmp/build/perf-tools-next/pmu-events/pmu-events.o
  LD      /tmp/build/perf-tools-next/pmu-events/pmu-events-in.o
make[1]: *** [Makefile.perf:236: sub-make] Error 2
make: *** [Makefile:113: install-bin] Error 2
make: Leaving directory '/var/home/acme/git/perf-tools-next/tools/perf'

 Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 O=/tmp/build/perf-tools-next -C tools/perf install-bin':

       61899912971      cycles:u                                                              
      106832920114      instructions:u                   #    1.73  insn per cycle            

       4.586621727 seconds time elapsed

      14.384368000 seconds user
       5.495604000 seconds sys


⬢[acme@toolbox perf-tools-next]$
diff mbox series

Patch

diff --git a/kernel/events/core.c b/kernel/events/core.c
index db016e418931..6039fdf00b3c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -8245,7 +8245,7 @@  static void perf_event_comm_event(struct perf_comm_event *comm_event)
 	unsigned int size;
 
 	memset(comm, 0, sizeof(comm));
-	strlcpy(comm, comm_event->task->comm, sizeof(comm));
+	strscpy(comm, comm_event->task->comm, sizeof(comm));
 	size = ALIGN(strlen(comm)+1, sizeof(u64));
 
 	comm_event->comm = comm;
@@ -8700,7 +8700,7 @@  static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
 	}
 
 cpy_name:
-	strlcpy(tmp, name, sizeof(tmp));
+	strscpy(tmp, name, sizeof(tmp));
 	name = tmp;
 got_name:
 	/*
@@ -9124,7 +9124,7 @@  void perf_event_ksymbol(u16 ksym_type, u64 addr, u32 len, bool unregister,
 	    ksym_type == PERF_RECORD_KSYMBOL_TYPE_UNKNOWN)
 		goto err;
 
-	strlcpy(name, sym, KSYM_NAME_LEN);
+	strscpy(name, sym, KSYM_NAME_LEN);
 	name_len = strlen(name) + 1;
 	while (!IS_ALIGNED(name_len, sizeof(u64)))
 		name[name_len++] = '\0';
diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c
index 5741ffe47312..91fe2ef920c7 100644
--- a/tools/perf/arch/x86/util/event.c
+++ b/tools/perf/arch/x86/util/event.c
@@ -64,7 +64,7 @@  int perf_event__synthesize_extra_kmaps(struct perf_tool *tool,
 		event->mmap.pgoff = map__pgoff(map);
 		event->mmap.pid   = machine->pid;
 
-		strlcpy(event->mmap.filename, kmap->name, PATH_MAX);
+		strscpy(event->mmap.filename, kmap->name, PATH_MAX);
 
 		if (perf_tool__process_synth_event(tool, event, machine,
 						   process) != 0) {
diff --git a/tools/perf/arch/x86/util/machine.c b/tools/perf/arch/x86/util/machine.c
index 31679c35d493..1ff0be147205 100644
--- a/tools/perf/arch/x86/util/machine.c
+++ b/tools/perf/arch/x86/util/machine.c
@@ -40,7 +40,7 @@  static int add_extra_kernel_map(struct extra_kernel_map_info *mi, u64 start,
 	mi->maps[mi->cnt].start = start;
 	mi->maps[mi->cnt].end   = end;
 	mi->maps[mi->cnt].pgoff = pgoff;
-	strlcpy(mi->maps[mi->cnt].name, name, KMAP_NAME_LEN);
+	strscpy(mi->maps[mi->cnt].name, name, KMAP_NAME_LEN);
 
 	mi->cnt += 1;
 
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index cd381693658b..0cc4c39558ad 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -36,7 +36,7 @@  static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
 	char root_dir[PATH_MAX];
 	char *p;
 
-	strlcpy(root_dir, proc_dir, sizeof(root_dir));
+	strscpy(root_dir, proc_dir, sizeof(root_dir));
 
 	p = strrchr(root_dir, '/');
 	if (!p)
@@ -104,7 +104,7 @@  static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
 			  to_dir, dent->d_name);
 		if (!compare_proc_modules(from, to) &&
 		    same_kallsyms_reloc(from_dir, to_subdir)) {
-			strlcpy(to_dir, to_subdir, to_dir_sz);
+			strscpy(to_dir, to_subdir, to_dir_sz);
 			ret = 0;
 			break;
 		}
@@ -121,7 +121,7 @@  static int build_id_cache__add_kcore(const char *filename, bool force)
 	char from_dir[PATH_MAX], to_dir[PATH_MAX];
 	char *p;
 
-	strlcpy(from_dir, filename, sizeof(from_dir));
+	strscpy(from_dir, filename, sizeof(from_dir));
 
 	p = strrchr(from_dir, '/');
 	if (!p || strcmp(p + 1, "kcore"))
diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c
index 34cbe3e959aa..aa6ebf46370a 100644
--- a/tools/perf/builtin-daemon.c
+++ b/tools/perf/builtin-daemon.c
@@ -606,7 +606,7 @@  static int setup_server_socket(struct daemon *daemon)
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
 
-	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+	strscpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
 	unlink(path);
 
 	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
@@ -877,7 +877,7 @@  static int setup_client_socket(struct daemon *daemon)
 
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
-	strlcpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+	strscpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
 
 	if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
 		perror("failed: connect");
diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c
index fcca275e5bf9..04d6825d23c8 100644
--- a/tools/perf/jvmti/libjvmti.c
+++ b/tools/perf/jvmti/libjvmti.c
@@ -158,7 +158,7 @@  copy_class_filename(const char * class_sign, const char * file_name, char * resu
 		result[i] = '\0';
 	} else {
 		/* fallback case */
-		strlcpy(result, file_name, max_length);
+		strscpy(result, file_name, max_length);
 	}
 }
 
diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c
index 086fd2179e41..7003418614ef 100644
--- a/tools/perf/tests/dlfilter-test.c
+++ b/tools/perf/tests/dlfilter-test.c
@@ -234,7 +234,7 @@  static int get_dlfilters_path(char *buf, size_t sz)
 		if (access(path, R_OK))
 			return -1;
 	}
-	strlcpy(buf, dirname(path), sz);
+	strscpy(buf, dirname(path), sz);
 	return 0;
 }
 
diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c
index 2d1aa42d36a9..a6b44fa4ec6f 100644
--- a/tools/perf/tests/symbols.c
+++ b/tools/perf/tests/symbols.c
@@ -45,7 +45,7 @@  static void exit_test_info(struct test_info *ti)
 static void get_test_dso_filename(char *filename, size_t max_sz)
 {
 	if (dso_to_test)
-		strlcpy(filename, dso_to_test, max_sz);
+		strscpy(filename, dso_to_test, max_sz);
 	else
 		perf_exe(filename, max_sz);
 }
diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c
index db4952f5990b..1040e4c33469 100644
--- a/tools/perf/ui/tui/helpline.c
+++ b/tools/perf/ui/tui/helpline.c
@@ -24,7 +24,7 @@  static void tui_helpline__push(const char *msg)
 	SLsmg_set_color(0);
 	SLsmg_write_nstring((char *)msg, SLtt_Screen_Cols);
 	SLsmg_refresh();
-	strlcpy(ui_helpline__current, msg, sz);
+	strscpy(ui_helpline__current, msg, sz);
 }
 
 static int tui_helpline__show(const char *format, va_list ap)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 11992cfe271c..5e1a623be915 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1702,7 +1702,7 @@  static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
 		if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) {
 			char *new_name = dso__filename_with_chroot(dso, filename);
 			if (new_name) {
-				strlcpy(filename, new_name, filename_size);
+				strscpy(filename, new_name, filename_size);
 				free(new_name);
 			}
 		}
@@ -2002,7 +2002,7 @@  static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
 		kce.len = sym->end - sym->start;
 		if (!kcore_extract__create(&kce)) {
 			delete_extract = true;
-			strlcpy(symfs_filename, kce.extract_filename,
+			strscpy(symfs_filename, kce.extract_filename,
 				sizeof(symfs_filename));
 		}
 	} else if (dso__needs_decompress(dso)) {
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index a0368202a746..e69841ba3014 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -1213,7 +1213,7 @@  void auxtrace_synth_guest_error(struct perf_record_auxtrace_error *auxtrace_erro
 	auxtrace_error->fmt = 1;
 	auxtrace_error->ip = ip;
 	auxtrace_error->time = timestamp;
-	strlcpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
+	strscpy(auxtrace_error->msg, msg, MAX_AUXTRACE_ERROR_MSG);
 	if (machine_pid) {
 		auxtrace_error->fmt = 2;
 		auxtrace_error->machine_pid = machine_pid;
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index a86614599269..7db2f30f6a0d 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -318,7 +318,7 @@  int filename__decompress(const char *name, char *pathname,
 		unlink(tmpbuf);
 
 	if (pathname && (fd >= 0))
-		strlcpy(pathname, tmpbuf, len);
+		strscpy(pathname, tmpbuf, len);
 
 	return fd;
 }
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index b450178e3420..5b14c6701ecb 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -507,7 +507,7 @@  int intel_pt__strerror(int code, char *buf, size_t buflen)
 {
 	if (code < 1 || code >= INTEL_PT_ERR_MAX)
 		code = INTEL_PT_ERR_UNK;
-	strlcpy(buf, intel_pt_err_msgs[code], buflen);
+	strscpy(buf, intel_pt_err_msgs[code], buflen);
 	return 0;
 }
 
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 4e8e243a6e4b..3d7c614adc80 100644
--- a/tools/perf/util/llvm-utils.c
+++ b/tools/perf/util/llvm-utils.c
@@ -80,7 +80,7 @@  search_program(const char *def, const char *name,
 	if (def && def[0] != '\0') {
 		if (def[0] == '/') {
 			if (access(def, F_OK) == 0) {
-				strlcpy(output, def, PATH_MAX);
+				strscpy(output, def, PATH_MAX);
 				return 0;
 			}
 		} else if (def[0] != '\0')
@@ -99,7 +99,7 @@  search_program(const char *def, const char *name,
 	while (path) {
 		scnprintf(buf, sizeof(buf), "%s/%s", path, name);
 		if (access(buf, F_OK) == 0) {
-			strlcpy(output, buf, PATH_MAX);
+			strscpy(output, buf, PATH_MAX);
 			ret = 0;
 			break;
 		}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9e02e19c1b7a..d035b35d226e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1223,7 +1223,7 @@  int machine__create_extra_kernel_map(struct machine *machine,
 
 	kmap = map__kmap(map);
 
-	strlcpy(kmap->name, xm->name, KMAP_NAME_LEN);
+	strscpy(kmap->name, xm->name, KMAP_NAME_LEN);
 
 	err = maps__insert(machine__kernel_maps(machine), map);
 
@@ -1314,7 +1314,7 @@  int machine__map_x86_64_entry_trampolines(struct machine *machine,
 			.pgoff = pgoff,
 		};
 
-		strlcpy(xm.name, ENTRY_TRAMPOLINE_NAME, KMAP_NAME_LEN);
+		strscpy(xm.name, ENTRY_TRAMPOLINE_NAME, KMAP_NAME_LEN);
 
 		if (machine__create_extra_kernel_map(machine, kernel, &xm) < 0)
 			return -1;
@@ -1935,7 +1935,7 @@  int machine__process_mmap2_event(struct machine *machine,
 			.pgoff = event->mmap2.pgoff,
 		};
 
-		strlcpy(xm.name, event->mmap2.filename, KMAP_NAME_LEN);
+		strscpy(xm.name, event->mmap2.filename, KMAP_NAME_LEN);
 		ret = machine__process_kernel_mmap_event(machine, &xm, bid);
 		if (ret < 0)
 			goto out_problem;
@@ -1992,7 +1992,7 @@  int machine__process_mmap_event(struct machine *machine, union perf_event *event
 			.pgoff = event->mmap.pgoff,
 		};
 
-		strlcpy(xm.name, event->mmap.filename, KMAP_NAME_LEN);
+		strscpy(xm.name, event->mmap.filename, KMAP_NAME_LEN);
 		ret = machine__process_kernel_mmap_event(machine, &xm, NULL);
 		if (ret < 0)
 			goto out_problem;
diff --git a/tools/perf/util/pmu-hybrid.c b/tools/perf/util/pmu-hybrid.c
index 38628805a952..1c6e7f7da856 100644
--- a/tools/perf/util/pmu-hybrid.c
+++ b/tools/perf/util/pmu-hybrid.c
@@ -27,7 +27,7 @@  bool perf_pmu__hybrid_mounted(const char *name)
 	if (strncmp(name, "cpu_", 4))
 		return false;
 
-	strlcpy(pmu_name, name, sizeof(pmu_name));
+	strscpy(pmu_name, name, sizeof(pmu_name));
 	return perf_pmu__scan_file(&pmu, "cpus", "%u", &cpu) > 0;
 }
 
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index ad209c88a124..7e2d97926e9f 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -599,7 +599,7 @@  static struct perf_cpu_map *pmu_cpumask(int dirfd, const char *name)
 	struct perf_pmu pmu = {.name = pmu_name};
 	FILE *file;
 
-	strlcpy(pmu_name, name, sizeof(pmu_name));
+	strscpy(pmu_name, name, sizeof(pmu_name));
 	for (template = templates; *template; template++) {
 		file = perf_pmu__open_file_at(&pmu, dirfd, *template);
 		if (!file)
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 3d50de3217d5..8bc90b856ce3 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -459,7 +459,7 @@  static int probe_cache__open(struct probe_cache *pcache, const char *target,
 
 	if (target && build_id_cache__cached(target)) {
 		/* This is a cached buildid */
-		strlcpy(sbuildid, target, SBUILD_ID_SIZE);
+		strscpy(sbuildid, target, SBUILD_ID_SIZE);
 		dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
 		goto found;
 	}
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 5c62d3118c41..dd877b259f75 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -332,7 +332,7 @@  static char *cpu_model(void)
 	if (file) {
 		while (fgets(buf, 255, file)) {
 			if (strstr(buf, "model name")) {
-				strlcpy(cpu_m, &buf[13], 255);
+				strscpy(cpu_m, &buf[13], 255);
 				break;
 			}
 		}
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 6b9c55784b56..57223c770b89 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1967,7 +1967,7 @@  int dso__load(struct dso *dso, struct map *map)
 			char *new_name = dso__filename_with_chroot(dso, name);
 			if (new_name) {
 				is_reg = is_regular_file(new_name);
-				strlcpy(name, new_name, PATH_MAX);
+				strscpy(name, new_name, PATH_MAX);
 				free(new_name);
 			}
 		}
@@ -2254,7 +2254,7 @@  static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
 		scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
 			  "%s/%s/kallsyms", dir, nd->s);
 		if (!validate_kcore_addresses(kallsyms_filename, map)) {
-			strlcpy(dir, kallsyms_filename, dir_sz);
+			strscpy(dir, kallsyms_filename, dir_sz);
 			ret = 0;
 			break;
 		}
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index b2e4afa5efa1..d7c13e3ded9f 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -1979,7 +1979,7 @@  int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evse
 	if (ev == NULL)
 		return -ENOMEM;
 
-	strlcpy(ev->unit, evsel->unit, size + 1);
+	strscpy(ev->unit, evsel->unit, size + 1);
 	err = process(tool, (union perf_event *)ev, NULL, NULL);
 	free(ev);
 	return err;
@@ -2013,7 +2013,7 @@  int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evse
 	if (ev == NULL)
 		return -ENOMEM;
 
-	strlcpy(ev->name, evsel->name, len + 1);
+	strscpy(ev->name, evsel->name, len + 1);
 	err = process(tool, (union perf_event *)ev, NULL, NULL);
 	free(ev);
 	return err;