Re: [PATCH 07/11] perf tools: Add O_CLOEXEC to open() calls in DSO and ELF code

From: Ian Rogers

Date: Mon Jun 08 2026 - 18:06:18 EST


On Mon, Jun 8, 2026 at 1:18 PM Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> wrote:
>
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> open() calls in dso.c and symbol-elf.c omit O_CLOEXEC, which leaks
> file descriptors to child processes spawned during symbol resolution
> (e.g., addr2line, objdump). This can exhaust the fd limit during
> long profiling sessions or when processing many DSOs.
>
> Add O_CLOEXEC to all open() calls in both files (12 call sites).
>
> Fixes: cdd059d731eeb466 ("perf tools: Move dso_* related functions into dso object")
> Fixes: e5a1845fc0aeca85 ("perf symbols: Split out util/symbol-elf.c")
> Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
> Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
> Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
> Assisted-by: Claude Opus 4.6 <noreply@xxxxxxxxxxxxx>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>
and Sashiko is asking for more of this goodness.

Thanks,
Ian

> ---
> tools/perf/util/dso.c | 4 ++--
> tools/perf/util/symbol-elf.c | 20 ++++++++++----------
> 2 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 7dced896c64eafd7..fb2e78fe2aa8eb94 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -344,7 +344,7 @@ int filename__decompress(const char *name, char *pathname,
> * descriptor to the uncompressed file.
> */
> if (!compressions[comp].is_compressed(name))
> - return open(name, O_RDONLY);
> + return open(name, O_RDONLY | O_CLOEXEC);
>
> fd = mkstemp(tmpbuf);
> if (fd < 0) {
> @@ -1911,7 +1911,7 @@ static const u8 *__dso__read_symbol(struct dso *dso, const char *symfs_filename,
> int saved_errno;
>
> nsinfo__mountns_enter(dso__nsinfo(dso), &nsc);
> - fd = open(symfs_filename, O_RDONLY);
> + fd = open(symfs_filename, O_RDONLY | O_CLOEXEC);
> saved_errno = errno;
> nsinfo__mountns_exit(&nsc);
> if (fd < 0) {
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 186e6d92ac3d7742..c2bdfd0003df2abe 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -217,7 +217,7 @@ bool filename__has_section(const char *filename, const char *sec)
> GElf_Shdr shdr;
> bool found = false;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC);
> if (fd < 0)
> return false;
>
> @@ -872,7 +872,7 @@ static int read_build_id(const char *filename, struct build_id *bid)
> if (size < BUILD_ID_SIZE)
> goto out;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC);
> if (fd < 0)
> goto out;
>
> @@ -935,7 +935,7 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid)
> size_t size = sizeof(bid->data);
> int fd, err = -1;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC);
> if (fd < 0)
> goto out;
>
> @@ -995,7 +995,7 @@ int filename__read_debuglink(const char *filename, char *debuglink,
> if (err >= 0)
> goto out;
>
> - fd = open(filename, O_RDONLY);
> + fd = open(filename, O_RDONLY | O_CLOEXEC);
> if (fd < 0)
> goto out;
>
> @@ -1153,7 +1153,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
>
> type = dso__symtab_type(dso);
> } else {
> - fd = open(name, O_RDONLY);
> + fd = open(name, O_RDONLY | O_CLOEXEC);
> if (fd < 0) {
> *dso__load_errno(dso) = errno;
> return -1;
> @@ -1952,7 +1952,7 @@ static int kcore__open(struct kcore *kcore, const char *filename)
> {
> GElf_Ehdr *ehdr;
>
> - kcore->fd = open(filename, O_RDONLY);
> + kcore->fd = open(filename, O_RDONLY | O_CLOEXEC);
> if (kcore->fd == -1)
> return -1;
>
> @@ -1985,7 +1985,7 @@ static int kcore__init(struct kcore *kcore, char *filename, int elfclass,
> if (temp)
> kcore->fd = mkstemp(filename);
> else
> - kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400);
> + kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0400);
> if (kcore->fd == -1)
> return -1;
>
> @@ -2461,11 +2461,11 @@ static int kcore_copy__compare_files(const char *from_filename,
> {
> int from, to, err = -1;
>
> - from = open(from_filename, O_RDONLY);
> + from = open(from_filename, O_RDONLY | O_CLOEXEC);
> if (from < 0)
> return -1;
>
> - to = open(to_filename, O_RDONLY);
> + to = open(to_filename, O_RDONLY | O_CLOEXEC);
> if (to < 0)
> goto out_close_from;
>
> @@ -2883,7 +2883,7 @@ int get_sdt_note_list(struct list_head *head, const char *target)
> Elf *elf;
> int fd, ret;
>
> - fd = open(target, O_RDONLY);
> + fd = open(target, O_RDONLY | O_CLOEXEC);
> if (fd < 0)
> return -EBADF;
>
> --
> 2.54.0
>