Linux Perf Users
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Arnaldo Carvalho de Melo" <acme@kernel.org>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [PATCH 4/5] perf dso: Guard against cache underflow on short reads in dso_cache__memcpy()
Date: Sun, 02 Aug 2026 14:54:33 +0000	[thread overview]
Message-ID: <20260802145434.3AA961F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260802142022.154219-5-acme@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Returning 0 from `dso_cache__memcpy()` causes a permanent EOF rather than triggering a cache miss and re-read as intended, breaking reads from dynamically growing files.

Pre-existing issues:
- [High] The RB-tree traversal in `__dso_cache__find()` is performed locklessly, creating a data race with concurrent cache insertions.
--

--- Patch [4]: [PATCH 4/5] perf dso: Guard against cache underflow on short reads in dso_cache__memcpy() ---
commit 06837abfd5cca9da5670ee54ec02e3164860900c
Author: Arnaldo Carvalho de Melo <acme@redhat.com>

perf dso: Guard against cache underflow on short reads in dso_cache__memcpy()

dso_cache__memcpy() computes cache_size based on cache->size, but a short
pread can leave cache->size smaller than the RB tree lookup window. This
causes a subtraction wrap-around and an out-of-bounds memcpy when accessed
past the cached size. This patch attempts to fix it by returning 0 (cache
miss) when the offset falls outside the valid cached range so the caller
re-reads from the backing file.

> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 207f8744aac97..a0de56c93592a 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -1002,7 +1002,17 @@ static ssize_t dso_cache__memcpy(struct dso_cache *cache, u64 offset, u8 *data,
>  				 u64 size, bool out)
>  {
>  	u64 cache_offset = offset - cache->offset;
> -	u64 cache_size   = min(cache->size - cache_offset, size);
> +	u64 cache_size;
> +
> +	/*
> +	 * The RB tree matches using DSO__DATA_CACHE_SIZE, but a short
> +	 * pread may leave cache->size smaller.  Treat an offset past
> +	 * the valid data as a cache miss so the caller re-reads.
> +	 */
> +	if (cache_offset >= cache->size)
> +		return 0;

[Severity: High]
Does returning 0 here actually trigger a re-read?

Looking at cached_io() which calls this function, it seems to treat a 0 return
value strictly as an EOF condition:

cached_io() {
    ...
    ret = dso_cache__memcpy(cache, offset, data, size, out);
    if (!ret)
        break;
    ...
}

If the file has grown and we hit this condition, won't this cause cached_io()
to terminate the loop with a silent EOF instead of reading the new data from
the backing file?

> +
> +	cache_size = min(cache->size - cache_offset, size);
>  
>  	if (out)
>  		memcpy(data, cache->data + cache_offset, cache_size);

[Severity: High]
This is a pre-existing issue, but I noticed a potential data race when looking
at the RB-tree lookups in this file.

In __dso_cache__find(), the RB-tree traversal is performed locklessly:

    while (*p != NULL) {
        ...
        cache = rb_entry(parent, struct dso_cache, rb_node);
        ...
        if (offset < cache->offset)
            p = &(*p)->rb_left;
        else if (offset >= end)
            p = &(*p)->rb_right;
    }

However, dso_cache__insert() modifies the RB-tree while correctly holding
the dso__lock(dso) mutex:

    mutex_lock(dso__lock(dso));
    ...
    rb_link_node(&new->rb_node, parent, p);
    rb_insert_color(&new->rb_node, root);

If a lockless reader in __dso_cache__find() traverses the tree concurrently
with a cache miss that triggers dso_cache__insert(), could the reader observe
inconsistent tree pointers during the rb_insert_color() rotations?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260802142022.154219-1-acme@kernel.org?part=4

  reply	other threads:[~2026-08-02 14:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-02 14:20 [PATCHES 0/5] perf DSO hardening series Arnaldo Carvalho de Melo
2026-08-02 14:20 ` [PATCH 1/5] perf dso: Guard against errno==0 when dso__get_filename() returns NULL Arnaldo Carvalho de Melo
2026-08-02 14:58   ` sashiko-bot
2026-08-02 21:38     ` Arnaldo Carvalho de Melo
2026-08-02 21:08   ` David Laight
2026-08-02 14:20 ` [PATCH 2/5] perf dso: Guard close() against invalid fd in dso__decompress_kmodule_path() Arnaldo Carvalho de Melo
2026-08-02 14:20 ` [PATCH 3/5] perf dso: Use stored fd error instead of stale errno in file_read() Arnaldo Carvalho de Melo
2026-08-02 14:20 ` [PATCH 4/5] perf dso: Guard against cache underflow on short reads in dso_cache__memcpy() Arnaldo Carvalho de Melo
2026-08-02 14:54   ` sashiko-bot [this message]
2026-08-02 14:20 ` [PATCH 5/5] perf dso: Replace assert with runtime check in dso__read_symbol() Arnaldo Carvalho de Melo
2026-08-02 14:54   ` sashiko-bot

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=20260802145434.3AA961F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=acme@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