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>
This commit is contained in:
parent
6f51352929
commit
c897899752
2 changed files with 7 additions and 1 deletions
|
@ -44,13 +44,16 @@ struct perf_event_attr;
|
|||
/* perf sample has 16 bits size limit */
|
||||
#define PERF_SAMPLE_MAX_SIZE (1 << 16)
|
||||
|
||||
/* number of register is bound by the number of bits in regs_dump::mask (64) */
|
||||
#define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64))
|
||||
|
||||
struct regs_dump {
|
||||
u64 abi;
|
||||
u64 mask;
|
||||
u64 *regs;
|
||||
|
||||
/* Cached values/mask filled by first register access. */
|
||||
u64 cache_regs[PERF_REGS_MAX];
|
||||
u64 cache_regs[PERF_SAMPLE_REGS_CACHE_SIZE];
|
||||
u64 cache_mask;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
|
|||
int i, idx = 0;
|
||||
u64 mask = regs->mask;
|
||||
|
||||
if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (regs->cache_mask & (1ULL << id))
|
||||
goto out;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue