]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
perf bpf: Validate func_info_rec_size and sub_id in synthesize_bpf_prog_name()
authorArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 11 Jun 2026 00:01:15 +0000 (21:01 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 17 Jun 2026 11:28:53 +0000 (08:28 -0300)
synthesize_bpf_prog_name() computes a pointer into the func_info array
using sub_id * info->func_info_rec_size without validating either value.
Both come from perf.data and are untrusted:

- A func_info_rec_size smaller than sizeof(struct bpf_func_info) means
  the finfo pointer would reference a truncated entry, reading past it
  into adjacent data.

- A sub_id >= nr_func_info computes an offset past the func_info buffer,
  causing an out-of-bounds read.

Add bounds checks for both values before computing the pointer offset.
When validation fails, fall through to the non-BTF name path instead
of reading garbage.

Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Fixes: 7b612e291a5affb1 ("perf tools: Synthesize PERF_RECORD_* for loaded BPF programs")
Cc: Song Liu <songliubraving@fb.com>
Assisted-by: Claude:claude-opus-4.6
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/bpf-event.c

index c4594969d76772388f441f323ed93496137fc2e5..fe6fbca508c5135cd1673469b3c23743aa360679 100644 (file)
@@ -143,7 +143,9 @@ static int synthesize_bpf_prog_name(char *buf, int size,
        name_len = scnprintf(buf, size, "bpf_prog_");
        name_len += snprintf_hex(buf + name_len, size - name_len,
                                 prog_tags[sub_id], BPF_TAG_SIZE);
-       if (btf) {
+       if (btf &&
+           info->func_info_rec_size >= sizeof(*finfo) &&
+           sub_id < info->nr_func_info) {
                finfo = func_infos + sub_id * info->func_info_rec_size;
                t = btf__type_by_id(btf, finfo->type_id);
                if (t)