Re: [PATCH 10/13] perf bpf: Reject oversized BPF metadata events that truncate header.size

From: Ian Rogers

Date: Mon Jun 15 2026 - 13:21:43 EST


On Fri, Jun 12, 2026 at 3:24 PM Arnaldo Carvalho de Melo
<acme@xxxxxxxxxx> wrote:
>
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>
> bpf_metadata_alloc() computes event_size from the number of BPF metadata
> variables and stores it in header.size, which is __u16. With 204 or
> more .rodata variables prefixed "bpf_metadata_", event_size exceeds
> 65535 and silently truncates.
>
> The truncated header.size causes synthesize_perf_record_bpf_metadata()
> to allocate a buffer sized by the truncated value, then memcpy the full
> event data into it — a heap buffer overflow.
>
> Add a check that event_size fits in __u16 before proceeding. BPF
> programs with that many metadata variables are exotic enough that
> silently dropping the metadata is acceptable.
>
> Reported-by: sashiko-bot <sashiko-bot@xxxxxxxxxx>
> Fixes: ab38e84ba9a80581 ("perf record: collect BPF metadata from existing BPF programs")
> Cc: Blake Jones <blakejones@xxxxxxxxxx>
> Assisted-by: Claude Opus 4.6 <noreply@xxxxxxxxxxxxx>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>

Reviewed-by: Ian Rogers <irogers@xxxxxxxxxx>

Thanks,
Ian

> ---
> tools/perf/util/bpf-event.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
> index fe6fbca508c5135c..57d53ba848359e12 100644
> --- a/tools/perf/util/bpf-event.c
> +++ b/tools/perf/util/bpf-event.c
> @@ -369,6 +369,15 @@ static struct bpf_metadata *bpf_metadata_alloc(__u32 nr_prog_tags,
>
> event_size = sizeof(metadata->event->bpf_metadata) +
> nr_variables * sizeof(metadata->event->bpf_metadata.entries[0]);
> + /*
> + * header.size is __u16. synthesize_perf_record_bpf_metadata()
> + * adds machine->id_hdr_size (up to ~64 bytes) after this, so
> + * leave headroom to prevent the final size from wrapping.
> + */
> + if (event_size > UINT16_MAX - 256) {
> + bpf_metadata_free(metadata);
> + return NULL;
> + }
> metadata->event = zalloc(event_size);
> if (!metadata->event) {
> bpf_metadata_free(metadata);
> --
> 2.54.0
>