Skip to content

Commit 4a400ef

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
selftests/bpf: verifier/map_in_map converted to inline assembly
Test verifier/map_in_map automatically converted to use inline assembly. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20230421174234.2391278-12-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent b427ca5 commit 4a400ef

3 files changed

Lines changed: 144 additions & 96 deletions

File tree

tools/testing/selftests/bpf/prog_tests/verifier.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "verifier_leak_ptr.skel.h"
3535
#include "verifier_loops1.skel.h"
3636
#include "verifier_lwt.skel.h"
37+
#include "verifier_map_in_map.skel.h"
3738
#include "verifier_map_ptr.skel.h"
3839
#include "verifier_map_ret_val.skel.h"
3940
#include "verifier_masking.skel.h"
@@ -119,6 +120,7 @@ void test_verifier_ld_ind(void) { RUN(verifier_ld_ind); }
119120
void test_verifier_leak_ptr(void) { RUN(verifier_leak_ptr); }
120121
void test_verifier_loops1(void) { RUN(verifier_loops1); }
121122
void test_verifier_lwt(void) { RUN(verifier_lwt); }
123+
void test_verifier_map_in_map(void) { RUN(verifier_map_in_map); }
122124
void test_verifier_map_ptr(void) { RUN(verifier_map_ptr); }
123125
void test_verifier_map_ret_val(void) { RUN(verifier_map_ret_val); }
124126
void test_verifier_masking(void) { RUN(verifier_masking); }
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Converted from tools/testing/selftests/bpf/verifier/map_in_map.c */
3+
4+
#include <linux/bpf.h>
5+
#include <bpf/bpf_helpers.h>
6+
#include "bpf_misc.h"
7+
8+
struct {
9+
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
10+
__uint(max_entries, 1);
11+
__type(key, int);
12+
__type(value, int);
13+
__array(values, struct {
14+
__uint(type, BPF_MAP_TYPE_ARRAY);
15+
__uint(max_entries, 1);
16+
__type(key, int);
17+
__type(value, int);
18+
});
19+
} map_in_map SEC(".maps");
20+
21+
SEC("socket")
22+
__description("map in map access")
23+
__success __success_unpriv __retval(0)
24+
__naked void map_in_map_access(void)
25+
{
26+
asm volatile (" \
27+
r1 = 0; \
28+
*(u32*)(r10 - 4) = r1; \
29+
r2 = r10; \
30+
r2 += -4; \
31+
r1 = %[map_in_map] ll; \
32+
call %[bpf_map_lookup_elem]; \
33+
if r0 == 0 goto l0_%=; \
34+
r1 = 0; \
35+
*(u32*)(r10 - 4) = r1; \
36+
r2 = r10; \
37+
r2 += -4; \
38+
r1 = r0; \
39+
call %[bpf_map_lookup_elem]; \
40+
l0_%=: r0 = 0; \
41+
exit; \
42+
" :
43+
: __imm(bpf_map_lookup_elem),
44+
__imm_addr(map_in_map)
45+
: __clobber_all);
46+
}
47+
48+
SEC("xdp")
49+
__description("map in map state pruning")
50+
__success __msg("processed 26 insns")
51+
__log_level(2) __retval(0) __flag(BPF_F_TEST_STATE_FREQ)
52+
__naked void map_in_map_state_pruning(void)
53+
{
54+
asm volatile (" \
55+
r1 = 0; \
56+
*(u32*)(r10 - 4) = r1; \
57+
r6 = r10; \
58+
r6 += -4; \
59+
r2 = r6; \
60+
r1 = %[map_in_map] ll; \
61+
call %[bpf_map_lookup_elem]; \
62+
if r0 != 0 goto l0_%=; \
63+
exit; \
64+
l0_%=: r2 = r6; \
65+
r1 = r0; \
66+
call %[bpf_map_lookup_elem]; \
67+
if r0 != 0 goto l1_%=; \
68+
r2 = r6; \
69+
r1 = %[map_in_map] ll; \
70+
call %[bpf_map_lookup_elem]; \
71+
if r0 != 0 goto l2_%=; \
72+
exit; \
73+
l2_%=: r2 = r6; \
74+
r1 = r0; \
75+
call %[bpf_map_lookup_elem]; \
76+
if r0 != 0 goto l1_%=; \
77+
exit; \
78+
l1_%=: r0 = *(u32*)(r0 + 0); \
79+
exit; \
80+
" :
81+
: __imm(bpf_map_lookup_elem),
82+
__imm_addr(map_in_map)
83+
: __clobber_all);
84+
}
85+
86+
SEC("socket")
87+
__description("invalid inner map pointer")
88+
__failure __msg("R1 pointer arithmetic on map_ptr prohibited")
89+
__failure_unpriv
90+
__naked void invalid_inner_map_pointer(void)
91+
{
92+
asm volatile (" \
93+
r1 = 0; \
94+
*(u32*)(r10 - 4) = r1; \
95+
r2 = r10; \
96+
r2 += -4; \
97+
r1 = %[map_in_map] ll; \
98+
call %[bpf_map_lookup_elem]; \
99+
if r0 == 0 goto l0_%=; \
100+
r1 = 0; \
101+
*(u32*)(r10 - 4) = r1; \
102+
r2 = r10; \
103+
r2 += -4; \
104+
r1 = r0; \
105+
r1 += 8; \
106+
call %[bpf_map_lookup_elem]; \
107+
l0_%=: r0 = 0; \
108+
exit; \
109+
" :
110+
: __imm(bpf_map_lookup_elem),
111+
__imm_addr(map_in_map)
112+
: __clobber_all);
113+
}
114+
115+
SEC("socket")
116+
__description("forgot null checking on the inner map pointer")
117+
__failure __msg("R1 type=map_value_or_null expected=map_ptr")
118+
__failure_unpriv
119+
__naked void on_the_inner_map_pointer(void)
120+
{
121+
asm volatile (" \
122+
r1 = 0; \
123+
*(u32*)(r10 - 4) = r1; \
124+
r2 = r10; \
125+
r2 += -4; \
126+
r1 = %[map_in_map] ll; \
127+
call %[bpf_map_lookup_elem]; \
128+
r1 = 0; \
129+
*(u32*)(r10 - 4) = r1; \
130+
r2 = r10; \
131+
r2 += -4; \
132+
r1 = r0; \
133+
call %[bpf_map_lookup_elem]; \
134+
r0 = 0; \
135+
exit; \
136+
" :
137+
: __imm(bpf_map_lookup_elem),
138+
__imm_addr(map_in_map)
139+
: __clobber_all);
140+
}
141+
142+
char _license[] SEC("license") = "GPL";

tools/testing/selftests/bpf/verifier/map_in_map.c

Lines changed: 0 additions & 96 deletions
This file was deleted.

0 commit comments

Comments
 (0)