On Thu, Jun 5, 2025 at 9:42 AM Ihor Solodrai <ihor.solodrai@xxxxxxxxx> wrote: > > On 6/5/25 9:24 AM, Andrii Nakryiko wrote: > > On Wed, Jun 4, 2025 at 3:28 PM Ihor Solodrai <isolodrai@xxxxxxxx> wrote: > >> > >> A test requires the following to happen: > >> * CONST_PTR_TO_MAP value is put on the stack > >> * then this value is checked for null > >> * the code in the null branch fails verification > >> > >> I was able to achieve this by using a stack allocated array of maps, > >> populated with values from a global map. This is the first test case: > >> map_ptr_is_never_null. > >> > >> The second test case (map_ptr_is_never_null_rb) involves an array of > >> ringbufs and attempts to recreate a common coding pattern [1]. > >> > >> [1] https://lore.kernel.org/bpf/CAEf4BzZNU0gX_sQ8k8JaLe1e+Veth3Rk=4x7MDhv=hQxvO8EDw@xxxxxxxxxxxxxx/ > >> > >> Suggested-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > >> Signed-off-by: Ihor Solodrai <isolodrai@xxxxxxxx> > >> --- > >> .../selftests/bpf/progs/verifier_map_in_map.c | 77 +++++++++++++++++++ > >> 1 file changed, 77 insertions(+) > >> > > > > LGTM overall > > > > Acked-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > > > >> diff --git a/tools/testing/selftests/bpf/progs/verifier_map_in_map.c b/tools/testing/selftests/bpf/progs/verifier_map_in_map.c > >> index 7d088ba99ea5..1dd5c6902c53 100644 > >> --- a/tools/testing/selftests/bpf/progs/verifier_map_in_map.c > >> +++ b/tools/testing/selftests/bpf/progs/verifier_map_in_map.c > >> @@ -139,4 +139,81 @@ __naked void on_the_inner_map_pointer(void) > >> : __clobber_all); > >> } > >> > >> +SEC("socket") > >> +int map_ptr_is_never_null(void *ctx) > >> +{ > >> + struct bpf_map *maps[2] = { 0 }; > >> + struct bpf_map *map = NULL; > >> + int __attribute__((aligned(8))) key = 0; > > > > aligned(8) makes any difference? > > Yes. If not aligned (explicitly or by accident), verification fails > with "math between fp pointer and register with unbounded min value is > not allowed" at maps[key]. See the log below. It's not clear to me why "aligned" changes code gen, but let's not rely on it. Try 'unsigned int key' instead. Also note that &key part pessimizes the code. Do for (...; i < 2; i++) {u32 key = i; &key } instead.