Linux Perf Users
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: sashiko-reviews@lists.linux.dev
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH v3 06/10] perf tools: Factor out dso__find_binary_type()
Date: Mon, 12 Oct 2026 12:50:33 -0700	[thread overview]
Message-ID: <as06CQ3EzPXwTvcO@google.com> (raw)
In-Reply-To: <sashiko-outbox-167683@kernel.org>

On Mon, Oct 12, 2026 at 05:38:32AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] perf: Deadlock in __dso__find_binary_type retry loop on non-recursive mutex
> - [High] perf: Invalid memory access/crash in close_first_dso() due to missing emptiness check
> - [High] perf: Loss of machine->root_dir context breaks guest/container path resolution
> - [Medium] perf: Stale errno causes spurious EMFILE failure and retry exhaustion
> --
> 
> commit 281cbe5b226891d2bef88be13adaa52f889f6f89
> Author: Namhyung Kim <namhyung@kernel.org>
> 
> perf tools: Factor out dso__find_binary_type()
> 
> This commit factors out the binary type detection logic for a DSO into a
> separate function, checking for a ".text" section under the DSO lock. It
> also introduces retry logic to handle file descriptor limits by closing
> an open DSO when EMFILE is encountered.
> 
> > diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> > index 913877b84b2d4..851b39c63ec86 100644
> > --- a/tools/perf/util/dso.c
> > +++ b/tools/perf/util/dso.c
> [ ... ]
> > @@ -833,34 +833,142 @@ void dso__data_close(struct dso *dso)
> [ ... ]
> >  	do {
> >  		dso__set_binary_type(dso, binary_type_data[i++]);
> >  
> > -		dso_data->fd = open_dso(dso, machine);
> > -		if (dso_data->fd >= 0)
> > -			goto out;
> > +		path = dso__get_filename(dso, "", &decomp, dso__binary_type(dso));
> 
> [Severity: High]
> Does hardcoding an empty string instead of propagating machine->root_dir
> break guest or container path resolution?
> 
> In the pre-existing code, try_to_open_dso() passed the machine down to
> open_dso(), which correctly resolved paths using machine->root_dir.
> 
> Because dso__find_binary_type() does not accept a machine parameter, it drops
> the root directory context. Any binary types requiring alternative root
> directories, such as DSO_BINARY_TYPE__GUEST_KMODULE, might incorrectly
> resolve against the host's root file system, preventing proper symbol
> decoding.
> 
> > +		if (path == NULL) {
> > +			if (errno == EMFILE)
> > +				goto open_err;
> > +			continue;
> > +		}
> > +
> > +		found = filename__has_section(path, ".text");
> > +		if (!found)
> > +			saved_errno = errno;
> 
> [Severity: Medium]
> Could this read a stale errno if filename__has_section() returns false
> gracefully?
> 
> If the ELF file is parsed successfully but lacks a .text section,
> filename__has_section() returns false without setting or clearing errno.
> 
> If a previous, completely unrelated system call set errno to EMFILE,
> saved_errno would take that stale value.

Ok, I'll clear errno before calling filename__has_section().

> 
> > +		dso__put_filename(dso, path, decomp);
> > +
> > +		if (found)
> > +			return dso__binary_type(dso);
> > +		else if (saved_errno == EMFILE)
> > +			goto open_err;
> 
> This might cause an incorrect detection of EMFILE, which could then be
> mistakenly interpreted as a file descriptor exhaustion failure, triggering
> the open_err retry loop.
> 
> [ ... ]
> > +static int __dso__find_binary_type(struct dso *dso, bool needs_open_lock)
> > +{
> > +	int ret;
> > +	int retry = 0;
> > +
> > +again:
> > +	mutex_lock(dso__lock(dso));
> > +	ret = dso__find_binary_type_locked(dso);
> > +	mutex_unlock(dso__lock(dso));
> > +
> > +	if (ret == -1 && retry++ < FIND_MAX_RETRY) {
> > +		if (needs_open_lock)
> > +			mutex_lock(dso__data_open_lock());
> > +		close_first_dso();
> 
> [Severity: High]
> Is it safe to call close_first_dso() unconditionally here?
> 
> If the global file descriptor limit is exhausted outside of the perf DSO
> cache, or if the EMFILE error is spuriously triggered by a stale errno on
> the very first DSO parsed, the list could be completely empty.
> 
> Looking at close_first_dso(), it extracts the first entry from the
> dso__data_open linked list via list_first_entry() and dereferences it
> without verifying if the list is empty:
> 
> tools/perf/util/dso.c:close_first_dso() {
>     ...
>     dso_data = list_first_entry(&dso__data_open, struct dso_data, open_entry);
>     ...
> }
> 
> If the list is empty, list_first_entry() resolves to an invalid pointer,
> causing a crash upon dereference. The pre-existing caller,
> check_data_close(), safely verified limits before closing.

Ok, I'll check the open count first.

> 
> > +		goto again;
> > +	}
> 
> [Severity: High]
> Does the goto again bypass unlocking the dso__data_open_lock?
> 
> If needs_open_lock is true and dso__find_binary_type_locked() returns -1,
> the retry loop executes mutex_lock(dso__data_open_lock()) and jumps to again
> without releasing the lock.
> 
> If it fails a second time, the code evaluates if (needs_open_lock) again and
> incorrectly calls mutex_lock(dso__data_open_lock()) a second time.
> 
> Because perf uses standard non-recursive mutexes by default, acquiring the
> lock a second time from the same thread could cause an immediate, permanent
> deadlock.

Oops, right.  I'll make sure it's call only once.

Thanks,
Namhyung


  reply	other threads:[~2026-10-12 19:50 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12  5:25 [PATCH v3 00/10] perf symbol: Properly set DSO binary/symtab types Namhyung Kim
2026-10-12  5:25 ` [PATCH v3 01/10] perf tools: Remove redundant dso data init Namhyung Kim
2026-10-12  5:30   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 02/10] perf tools: Try linked debug files for DSO debug info Namhyung Kim
2026-10-12  5:35   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 03/10] perf symbol: Update symtab type of vmlinux from build-id cache Namhyung Kim
2026-10-12  5:38   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 04/10] perf symbol: Set binary/symtab type for split kallsyms Namhyung Kim
2026-10-12  5:33   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 05/10] perf symbol: Get rid of machine_or_dso_e_machine() Namhyung Kim
2026-10-12  5:44   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 06/10] perf tools: Factor out dso__find_binary_type() Namhyung Kim
2026-10-12  5:38   ` sashiko-bot
2026-10-12 19:50     ` Namhyung Kim [this message]
2026-10-12 21:37   ` Ian Rogers
2026-10-12  5:25 ` [PATCH v3 07/10] perf symbol: Set binary type for JIT map DSOs Namhyung Kim
2026-10-12  5:34   ` sashiko-bot
2026-10-12  5:25 ` [PATCH v3 08/10] perf symbol: Do not set binary type from symtab type Namhyung Kim
2026-10-12  5:38   ` sashiko-bot
2026-10-12  5:26 ` [PATCH v3 09/10] perf annotate: Simplify symbol__disassemble() with dso binary_type Namhyung Kim
2026-10-12  5:36   ` sashiko-bot
2026-10-12  5:26 ` [PATCH v3 10/10] perf test: Fix dso data tests Namhyung Kim
2026-10-12  5:37   ` sashiko-bot
2026-10-12 21:41 ` [PATCH v3 00/10] perf symbol: Properly set DSO binary/symtab types Ian Rogers
2026-10-12 23:07   ` Namhyung Kim

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=as06CQ3EzPXwTvcO@google.com \
    --to=namhyung@kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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