Re: [RFC bpf-next v2 0/1] libbpf: add compile-time OOB warning to bpf_tail_call_static

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Sep 5, 2025 at 1:42 AM Shung-Hsi Yu <shung-hsi.yu@xxxxxxxx> wrote:
>
> Adding some context that I think was miss per off-list discussion with
> Hoyeon.
>
> On Fri, Sep 05, 2025 at 02:18:11PM +0900, Hoyeon Lee wrote:
> > This RFC adds a compile-time check to bpf_tail_call_static() to warn
> > when a constant slot(index) is >= map->max_entries. This uses a small
> > BPF_MAP_ENTRIES() macro together with Clang's diagnose_if attribute.
>
> This is an attempt to see if it is possible to warn user of out-of-bound
> tail calls, with the assumption being that with bpf_tail_call_static()
> users would not be intentionally calling with an index that is superior
> to the number of entries.
>
> However, there concerns with the current implementation, so this is
> being sent as RFC to gather feedback, and to see if it can be better
> done. Currently the concerns are:
> - use macro to override bpf_tail_call_static()
> - only works for Clang and not GCC
> - uncertain whether this fit into libbpf conventions

- map definition's max_entries can be set from user space at runtime
making this check actively wrong


This diagnose_if attribute seems very useful, but I'm not sure we
should do this for anything map-related because statically provided
map attributes are all overridable from user space when loading BPF
object.

>
> > Clang front-end keeps the map type with a '(*max_entries)[N]' field,
> > so the expression
> >
> >     sizeof(*(m)->max_entries) / sizeof(**(m)->max_entries)
> >
> > is resolved to N entirely at compile time. This allows diagnose_if()
> > to emit a warning when a constant slot index is out of range.
> >
> > Example:
> >
> >     struct { /* BPF_MAP_TYPE_PROG_ARRAY = 3 */
> >         __uint(type, 3);             // int (*type)[3];
> >         __uint(max_entries, 100);    // int (*max_entries)[100];
> >         __type(key, __u32);          // typeof(__u32) *key;
> >         __type(value, __u32);        // typeof(__u32) *value;
> >     } progs SEC(".maps");
> >
> >     bpf_tail_call_static(ctx, &progs, 111);
> >
> > produces:
> >
> >     bound.bpf.c:26:9: warning: bpf_tail_call: slot >= max_entries [-Wuser-defined-warnings]
> >        26 |         bpf_tail_call_static(ctx, &progs, 111);
> >           |         ^
> >     /usr/local/include/bpf/bpf_helpers.h:190:54: note: expanded from macro 'bpf_tail_call_static'
> >       190 |          __bpf_tail_call_warn(__slot >= BPF_MAP_ENTRIES(map));                  \
> >           |                                                             ^
> >     /usr/local/include/bpf/bpf_helpers.h:183:20: note: from 'diagnose_if' attribute on '__bpf_tail_call_warn':
> >       183 |     __attribute__((diagnose_if(oob, "bpf_tail_call: slot >= max_entries", "warning")));
> >           |                    ^           ~~~
> >
> > Out-of-bounds tail call checkup is no-ops at runtime. Emitting a
> > compile-time warning can help developers detect mistakes earlier. The
> > check is currently limited to Clang (due to diagnose_if) and constant
> > indices, but should catch common errors.
> ...





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux