Skip to content

Commit c897899

Browse files
German Gomezacmel
authored andcommitted
perf tools: Prevent out-of-bounds access to registers
The size of the cache of register values is arch-dependant (PERF_REGS_MAX). This has the potential of causing an out-of-bounds access in the function "perf_reg_value" if the local architecture contains less registers than the one the perf.data file was recorded on. Since the maximum number of registers is bound by the bitmask "u64 cache_mask", and the size of the cache when running under x86 systems is 64 already, fix the size to 64 and add a range-check to the function "perf_reg_value" to prevent out-of-bounds access. Reported-by: Alexandre Truong <[email protected]> Reviewed-by: Kajol Jain <[email protected]> Signed-off-by: German Gomez <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: John Garry <[email protected]> Cc: Leo Yan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Will Deacon <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 6f51352 commit c897899

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

tools/perf/util/event.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ struct perf_event_attr;
4444
/* perf sample has 16 bits size limit */
4545
#define PERF_SAMPLE_MAX_SIZE (1 << 16)
4646

47+
/* number of register is bound by the number of bits in regs_dump::mask (64) */
48+
#define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64))
49+
4750
struct regs_dump {
4851
u64 abi;
4952
u64 mask;
5053
u64 *regs;
5154

5255
/* Cached values/mask filled by first register access. */
53-
u64 cache_regs[PERF_REGS_MAX];
56+
u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE];
5457
u64 cache_mask;
5558
};
5659

tools/perf/util/perf_regs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
2525
int i, idx = 0;
2626
u64 mask = regs->mask;
2727

28+
if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE)
29+
return -EINVAL;
30+
2831
if (regs->cache_mask & (1ULL << id))
2932
goto out;
3033

0 commit comments

Comments
 (0)