Skip to content

Commit c897899

Browse files
german-armacmel
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 <alexandre.truong@arm.com> Reviewed-by: Kajol Jain <kjain@linux.ibm.com> Signed-off-by: German Gomez <german.gomez@arm.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: John Garry <john.garry@huawei.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Poirier <mathieu.poirier@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-csky@vger.kernel.org Cc: linux-riscv@lists.infradead.org Link: https://lore.kernel.org/r/20211201123334.679131-2-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 6f51352 commit c897899

2 files changed

Lines changed: 7 additions & 1 deletion

File tree

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)