perf header: Sanity check HEADER_BPF_PROG_INFO

Add validation to process_bpf_prog_info() to harden against malformed
perf.data files:

- Upper bound on BPF program count (max 131072)
- Upper bound on per-program data_len (max 256MB)

Cc: Ian Rogers <irogers@google.com>
Assisted-by: Claude Code:claude-opus-4-6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Arnaldo Carvalho de Melo
2026-04-10 19:09:04 -03:00
committed by Namhyung Kim
parent f5722a6b6a
commit 66af7e9b05

View File

@@ -63,6 +63,8 @@
#include <event-parse.h>
#endif
#define MAX_BPF_DATA_LEN (256 * 1024 * 1024)
#define MAX_BPF_PROGS 131072
#define MAX_CACHE_ENTRIES 32768
#define MAX_GROUP_DESC 32768
#define MAX_NUMA_NODES 4096
@@ -3525,6 +3527,18 @@ static int process_bpf_prog_info(struct feat_fd *ff __maybe_unused, void *data _
if (do_read_u32(ff, &count))
return -1;
if (count > MAX_BPF_PROGS) {
pr_err("Invalid HEADER_BPF_PROG_INFO: count (%u) > %u\n",
count, MAX_BPF_PROGS);
return -1;
}
if (ff->size < sizeof(u32) + count * (2 * sizeof(u32) + sizeof(u64))) {
pr_err("Invalid HEADER_BPF_PROG_INFO: section too small (%zu) for %u entries\n",
ff->size, count);
return -1;
}
down_write(&env->bpf_progs.lock);
for (i = 0; i < count; ++i) {
@@ -3542,6 +3556,12 @@ static int process_bpf_prog_info(struct feat_fd *ff __maybe_unused, void *data _
goto out;
}
if (data_len > MAX_BPF_DATA_LEN) {
pr_warning("Invalid HEADER_BPF_PROG_INFO: data_len (%u) too large\n",
data_len);
goto out;
}
info_linear = malloc(sizeof(struct perf_bpil) +
data_len);
if (!info_linear)