All of lore.kernel.org
 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 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.