From: Arnaldo Carvalho de Melo Date: Fri, 10 Apr 2026 22:09:04 +0000 (-0300) Subject: perf header: Sanity check HEADER_BPF_PROG_INFO X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=66af7e9b05c4e7ff435c0aef0d253a65d290f03c;p=thirdparty%2Flinux.git 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 Assisted-by: Claude Code:claude-opus-4-6 Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Namhyung Kim --- diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 37c1afbc08167..705f1ab44bc93 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -63,6 +63,8 @@ #include #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)