Re: [PATCH 3/9] perf thread-stack: Bound wrapped branch stack copy

Adrian Hunter <[email protected]>
Newsgroups org.kernel.vger.linux-doc,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-perf-users
Organization Intel Finland Oy, Registered Address: c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo, Business Identity Code: 0357606 - 4, Domiciled in Helsinki
Message-ID <[email protected]>
On 03/08/2026 12:06, Amir Ayupov wrote:
> When the internal branch ring has wrapped, thread_stack__br_sample()
> computes the number of entries that still fit in the destination:
> 
> 	nr = min(ts->br_stack_pos, sz);
> 
> but then copies ts->br_stack_pos entries regardless, overrunning the
> destination whenever sz is smaller than ts->br_stack_pos.
> 
> No caller can trigger this today: both intel-pt and cs-etm size the
> thread stack ring and the output buffer from the same
> synth_opts.last_branch_sz, so sz is never less than ts->br_stack_sz and
> the two values always agree. It becomes reachable as soon as a caller
> keeps a larger reconstruction ring than the requested output depth,
> which is what --itrace=L does for late branch sampling.
> 
> Copy nr entries instead, so the destination bound is honoured whatever
> the caller asks for.
> 
> Signed-off-by: Amir Ayupov <[email protected]>
> ---
>  tools/perf/util/thread-stack.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
> index 1a3dffa83bde2..51eaedb47bb1d 100644
> --- a/tools/perf/util/thread-stack.c
> +++ b/tools/perf/util/thread-stack.c
> @@ -643,7 +643,7 @@ void thread_stack__br_sample(struct thread *thread, int cpu,
>  		sz -= nr;
>  		be = &dst->entries[nr];
>  		nr = min(ts->br_stack_pos, sz);
> -		memcpy(be, &src->entries[0], bsz * ts->br_stack_pos);
> +		memcpy(be, &src->entries[0], bsz * nr);
>  	}
>  }
>  

Has since been done:

commit ab9c84d1cd59e6b3b73de34982a35a76e3a9b032
Author: Arnaldo Carvalho de Melo <[email protected]>
Date:   Mon Jul 27 13:17:01 2026 -0300

    perf thread-stack: Fix heap buffer overflow on branch stack wrap copy
    
    thread_stack__br_sample() copies the wrap-around portion of the branch
    stack ring buffer with:
    
      nr = min(ts->br_stack_pos, sz);
      memcpy(be, &src->entries[0], bsz * ts->br_stack_pos);
    
    'nr' is correctly bounded to min(br_stack_pos, sz) but the memcpy uses
    the unbounded ts->br_stack_pos directly.  When br_stack_pos exceeds
    the remaining destination space 'sz', this writes past the destination
    buffer.
    
    Use 'nr' (the bounded value) in the memcpy size, matching the pattern
    of the first memcpy in the same function.
    
    Fixes: 86d67180b920 ("perf thread-stack: Add branch stack support")
    Reported-by: sashiko-bot <[email protected]>
    Assisted-by: Claude:claude-opus-4.6
    Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
    Reviewed-by: James Clark <[email protected]>
    Reviewed-by: Adrian Hunter <[email protected]>
    Signed-off-by: Namhyung Kim <[email protected]>

diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index c5ce741b0744..1360f44421ef 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -642,7 +642,7 @@ void thread_stack__br_sample(struct thread *thread, int cpu,
                sz -= nr;
                be = &dst->entries[nr];
                nr = min(ts->br_stack_pos, sz);
-               memcpy(be, &src->entries[0], bsz * ts->br_stack_pos);
+               memcpy(be, &src->entries[0], bsz * nr);
        }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.