* [PATCH 0/1] perf util: fix out-of-bounds write in perf_exe()
@ 2026-05-26 11:08 Miguel Martín Gil
2026-05-26 11:08 ` [PATCH 1/1] perf util: fix perf_exe() buffer write past end Miguel Martín Gil
0 siblings, 1 reply; 4+ messages in thread
From: Miguel Martín Gil @ 2026-05-26 11:08 UTC (permalink / raw)
To: linux-perf-users
Cc: linux-kernel, peterz, mingo, acme, namhyung,
Miguel Martín Gil
perf_exe() currently passes the full buffer length to readlink() and then
unconditionally appends a trailing NUL at buf[n].
When readlink() returns exactly len bytes, the NUL store lands one byte past
the end of the caller buffer.
This series fixes it by reading at most len - 1 bytes and keeping explicit NUL
termination only within bounds. It also hardens the fallback path for tiny
buffers so copying "perf" cannot overflow.
Miguel Martín Gil (1):
perf util: fix perf_exe() buffer write past end
tools/perf/util/util.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/1] perf util: fix perf_exe() buffer write past end
2026-05-26 11:08 [PATCH 0/1] perf util: fix out-of-bounds write in perf_exe() Miguel Martín Gil
@ 2026-05-26 11:08 ` Miguel Martín Gil
2026-05-26 15:05 ` Ian Rogers
0 siblings, 1 reply; 4+ messages in thread
From: Miguel Martín Gil @ 2026-05-26 11:08 UTC (permalink / raw)
To: linux-perf-users
Cc: linux-kernel, peterz, mingo, acme, namhyung,
Miguel Martín Gil
perf_exe() passes len to readlink() and then unconditionally writes a trailing NUL at buf[n]. If readlink() returns len, the write lands one byte past the buffer.
Read at most len - 1 bytes and keep the existing NUL termination. Also guard the fallback path for tiny buffers so copying "perf" cannot overflow.
Signed-off-by: Miguel Martín Gil <miguel.martin.gil.uni@gmail.com>
---
tools/perf/util/util.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 25849434f0a4..2c2a5c449ffd 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -419,11 +419,21 @@ int perf_tip(char **strp, const char *dirpath)
char *perf_exe(char *buf, int len)
{
- int n = readlink("/proc/self/exe", buf, len);
+ int n;
+
+ if (len <= 0)
+ return buf;
+
+ n = readlink("/proc/self/exe", buf, len - 1);
if (n > 0) {
buf[n] = 0;
return buf;
}
+ if (len < (int)sizeof("perf")) {
+ buf[0] = '\0';
+ return buf;
+ }
+
return strcpy(buf, "perf");
}
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] perf util: fix perf_exe() buffer write past end
2026-05-26 11:08 ` [PATCH 1/1] perf util: fix perf_exe() buffer write past end Miguel Martín Gil
@ 2026-05-26 15:05 ` Ian Rogers
2026-05-30 0:18 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 4+ messages in thread
From: Ian Rogers @ 2026-05-26 15:05 UTC (permalink / raw)
To: Miguel Martín Gil
Cc: linux-perf-users, linux-kernel, peterz, mingo, acme, namhyung
On Tue, May 26, 2026 at 4:10 AM Miguel Martín Gil
<miguel.martin.gil.uni@gmail.com> wrote:
>
> perf_exe() passes len to readlink() and then unconditionally writes a trailing NUL at buf[n]. If readlink() returns len, the write lands one byte past the buffer.
>
> Read at most len - 1 bytes and keep the existing NUL termination. Also guard the fallback path for tiny buffers so copying "perf" cannot overflow.
>
> Signed-off-by: Miguel Martín Gil <miguel.martin.gil.uni@gmail.com>
Reviewed-by: Ian Rogers <irogers@google.com>
and Sashiko is green:
https://sashiko.dev/#/patchset/20260526110852.7259-2-miguel.martin.gil.uni%40gmail.com
Thanks,
Ian
> ---
> tools/perf/util/util.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
> index 25849434f0a4..2c2a5c449ffd 100644
> --- a/tools/perf/util/util.c
> +++ b/tools/perf/util/util.c
> @@ -419,11 +419,21 @@ int perf_tip(char **strp, const char *dirpath)
>
> char *perf_exe(char *buf, int len)
> {
> - int n = readlink("/proc/self/exe", buf, len);
> + int n;
> +
> + if (len <= 0)
> + return buf;
> +
> + n = readlink("/proc/self/exe", buf, len - 1);
> if (n > 0) {
> buf[n] = 0;
> return buf;
> }
> + if (len < (int)sizeof("perf")) {
> + buf[0] = '\0';
> + return buf;
> + }
> +
> return strcpy(buf, "perf");
> }
>
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/1] perf util: fix perf_exe() buffer write past end
2026-05-26 15:05 ` Ian Rogers
@ 2026-05-30 0:18 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2026-05-30 0:18 UTC (permalink / raw)
To: Ian Rogers
Cc: Miguel Martín Gil, linux-perf-users, linux-kernel, peterz,
mingo, namhyung
On Tue, May 26, 2026 at 08:05:44AM -0700, Ian Rogers wrote:
> On Tue, May 26, 2026 at 4:10 AM Miguel Martín Gil
> <miguel.martin.gil.uni@gmail.com> wrote:
> >
> > perf_exe() passes len to readlink() and then unconditionally writes a trailing NUL at buf[n]. If readlink() returns len, the write lands one byte past the buffer.
> >
> > Read at most len - 1 bytes and keep the existing NUL termination. Also guard the fallback path for tiny buffers so copying "perf" cannot overflow.
> >
> > Signed-off-by: Miguel Martín Gil <miguel.martin.gil.uni@gmail.com>
>
> Reviewed-by: Ian Rogers <irogers@google.com>
>
> and Sashiko is green:
> https://sashiko.dev/#/patchset/20260526110852.7259-2-miguel.martin.gil.uni%40gmail.com
Thanks, applied to perf-tools-next, for v7.2.
- Arnaldo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-30 0:18 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26 11:08 [PATCH 0/1] perf util: fix out-of-bounds write in perf_exe() Miguel Martín Gil
2026-05-26 11:08 ` [PATCH 1/1] perf util: fix perf_exe() buffer write past end Miguel Martín Gil
2026-05-26 15:05 ` Ian Rogers
2026-05-30 0:18 ` Arnaldo Carvalho de Melo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.