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
next prev parent 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