1*efe25a33SEduard Zingerman // SPDX-License-Identifier: GPL-2.0
2*efe25a33SEduard Zingerman /* Converted from tools/testing/selftests/bpf/verifier/value_illegal_alu.c */
3*efe25a33SEduard Zingerman
4*efe25a33SEduard Zingerman #include <linux/bpf.h>
5*efe25a33SEduard Zingerman #include <bpf/bpf_helpers.h>
6*efe25a33SEduard Zingerman #include "bpf_misc.h"
7*efe25a33SEduard Zingerman
8*efe25a33SEduard Zingerman #define MAX_ENTRIES 11
9*efe25a33SEduard Zingerman
10*efe25a33SEduard Zingerman struct test_val {
11*efe25a33SEduard Zingerman unsigned int index;
12*efe25a33SEduard Zingerman int foo[MAX_ENTRIES];
13*efe25a33SEduard Zingerman };
14*efe25a33SEduard Zingerman
15*efe25a33SEduard Zingerman struct {
16*efe25a33SEduard Zingerman __uint(type, BPF_MAP_TYPE_HASH);
17*efe25a33SEduard Zingerman __uint(max_entries, 1);
18*efe25a33SEduard Zingerman __type(key, long long);
19*efe25a33SEduard Zingerman __type(value, struct test_val);
20*efe25a33SEduard Zingerman } map_hash_48b SEC(".maps");
21*efe25a33SEduard Zingerman
22*efe25a33SEduard Zingerman SEC("socket")
23*efe25a33SEduard Zingerman __description("map element value illegal alu op, 1")
24*efe25a33SEduard Zingerman __failure __msg("R0 bitwise operator &= on pointer")
25*efe25a33SEduard Zingerman __failure_unpriv
value_illegal_alu_op_1(void)26*efe25a33SEduard Zingerman __naked void value_illegal_alu_op_1(void)
27*efe25a33SEduard Zingerman {
28*efe25a33SEduard Zingerman asm volatile (" \
29*efe25a33SEduard Zingerman r2 = r10; \
30*efe25a33SEduard Zingerman r2 += -8; \
31*efe25a33SEduard Zingerman r1 = 0; \
32*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r1; \
33*efe25a33SEduard Zingerman r1 = %[map_hash_48b] ll; \
34*efe25a33SEduard Zingerman call %[bpf_map_lookup_elem]; \
35*efe25a33SEduard Zingerman if r0 == 0 goto l0_%=; \
36*efe25a33SEduard Zingerman r0 &= 8; \
37*efe25a33SEduard Zingerman r1 = 22; \
38*efe25a33SEduard Zingerman *(u64*)(r0 + 0) = r1; \
39*efe25a33SEduard Zingerman l0_%=: exit; \
40*efe25a33SEduard Zingerman " :
41*efe25a33SEduard Zingerman : __imm(bpf_map_lookup_elem),
42*efe25a33SEduard Zingerman __imm_addr(map_hash_48b)
43*efe25a33SEduard Zingerman : __clobber_all);
44*efe25a33SEduard Zingerman }
45*efe25a33SEduard Zingerman
46*efe25a33SEduard Zingerman SEC("socket")
47*efe25a33SEduard Zingerman __description("map element value illegal alu op, 2")
48*efe25a33SEduard Zingerman __failure __msg("R0 32-bit pointer arithmetic prohibited")
49*efe25a33SEduard Zingerman __failure_unpriv
value_illegal_alu_op_2(void)50*efe25a33SEduard Zingerman __naked void value_illegal_alu_op_2(void)
51*efe25a33SEduard Zingerman {
52*efe25a33SEduard Zingerman asm volatile (" \
53*efe25a33SEduard Zingerman r2 = r10; \
54*efe25a33SEduard Zingerman r2 += -8; \
55*efe25a33SEduard Zingerman r1 = 0; \
56*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r1; \
57*efe25a33SEduard Zingerman r1 = %[map_hash_48b] ll; \
58*efe25a33SEduard Zingerman call %[bpf_map_lookup_elem]; \
59*efe25a33SEduard Zingerman if r0 == 0 goto l0_%=; \
60*efe25a33SEduard Zingerman w0 += 0; \
61*efe25a33SEduard Zingerman r1 = 22; \
62*efe25a33SEduard Zingerman *(u64*)(r0 + 0) = r1; \
63*efe25a33SEduard Zingerman l0_%=: exit; \
64*efe25a33SEduard Zingerman " :
65*efe25a33SEduard Zingerman : __imm(bpf_map_lookup_elem),
66*efe25a33SEduard Zingerman __imm_addr(map_hash_48b)
67*efe25a33SEduard Zingerman : __clobber_all);
68*efe25a33SEduard Zingerman }
69*efe25a33SEduard Zingerman
70*efe25a33SEduard Zingerman SEC("socket")
71*efe25a33SEduard Zingerman __description("map element value illegal alu op, 3")
72*efe25a33SEduard Zingerman __failure __msg("R0 pointer arithmetic with /= operator")
73*efe25a33SEduard Zingerman __failure_unpriv
value_illegal_alu_op_3(void)74*efe25a33SEduard Zingerman __naked void value_illegal_alu_op_3(void)
75*efe25a33SEduard Zingerman {
76*efe25a33SEduard Zingerman asm volatile (" \
77*efe25a33SEduard Zingerman r2 = r10; \
78*efe25a33SEduard Zingerman r2 += -8; \
79*efe25a33SEduard Zingerman r1 = 0; \
80*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r1; \
81*efe25a33SEduard Zingerman r1 = %[map_hash_48b] ll; \
82*efe25a33SEduard Zingerman call %[bpf_map_lookup_elem]; \
83*efe25a33SEduard Zingerman if r0 == 0 goto l0_%=; \
84*efe25a33SEduard Zingerman r0 /= 42; \
85*efe25a33SEduard Zingerman r1 = 22; \
86*efe25a33SEduard Zingerman *(u64*)(r0 + 0) = r1; \
87*efe25a33SEduard Zingerman l0_%=: exit; \
88*efe25a33SEduard Zingerman " :
89*efe25a33SEduard Zingerman : __imm(bpf_map_lookup_elem),
90*efe25a33SEduard Zingerman __imm_addr(map_hash_48b)
91*efe25a33SEduard Zingerman : __clobber_all);
92*efe25a33SEduard Zingerman }
93*efe25a33SEduard Zingerman
94*efe25a33SEduard Zingerman SEC("socket")
95*efe25a33SEduard Zingerman __description("map element value illegal alu op, 4")
96*efe25a33SEduard Zingerman __failure __msg("invalid mem access 'scalar'")
97*efe25a33SEduard Zingerman __failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited")
__flag(BPF_F_ANY_ALIGNMENT)98*efe25a33SEduard Zingerman __flag(BPF_F_ANY_ALIGNMENT)
99*efe25a33SEduard Zingerman __naked void value_illegal_alu_op_4(void)
100*efe25a33SEduard Zingerman {
101*efe25a33SEduard Zingerman asm volatile (" \
102*efe25a33SEduard Zingerman r2 = r10; \
103*efe25a33SEduard Zingerman r2 += -8; \
104*efe25a33SEduard Zingerman r1 = 0; \
105*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r1; \
106*efe25a33SEduard Zingerman r1 = %[map_hash_48b] ll; \
107*efe25a33SEduard Zingerman call %[bpf_map_lookup_elem]; \
108*efe25a33SEduard Zingerman if r0 == 0 goto l0_%=; \
109*efe25a33SEduard Zingerman r0 = be64 r0; \
110*efe25a33SEduard Zingerman r1 = 22; \
111*efe25a33SEduard Zingerman *(u64*)(r0 + 0) = r1; \
112*efe25a33SEduard Zingerman l0_%=: exit; \
113*efe25a33SEduard Zingerman " :
114*efe25a33SEduard Zingerman : __imm(bpf_map_lookup_elem),
115*efe25a33SEduard Zingerman __imm_addr(map_hash_48b)
116*efe25a33SEduard Zingerman : __clobber_all);
117*efe25a33SEduard Zingerman }
118*efe25a33SEduard Zingerman
119*efe25a33SEduard Zingerman SEC("socket")
120*efe25a33SEduard Zingerman __description("map element value illegal alu op, 5")
121*efe25a33SEduard Zingerman __failure __msg("R0 invalid mem access 'scalar'")
122*efe25a33SEduard Zingerman __msg_unpriv("leaking pointer from stack off -8")
__flag(BPF_F_ANY_ALIGNMENT)123*efe25a33SEduard Zingerman __flag(BPF_F_ANY_ALIGNMENT)
124*efe25a33SEduard Zingerman __naked void value_illegal_alu_op_5(void)
125*efe25a33SEduard Zingerman {
126*efe25a33SEduard Zingerman asm volatile (" \
127*efe25a33SEduard Zingerman r2 = r10; \
128*efe25a33SEduard Zingerman r2 += -8; \
129*efe25a33SEduard Zingerman r1 = 0; \
130*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r1; \
131*efe25a33SEduard Zingerman r1 = %[map_hash_48b] ll; \
132*efe25a33SEduard Zingerman call %[bpf_map_lookup_elem]; \
133*efe25a33SEduard Zingerman if r0 == 0 goto l0_%=; \
134*efe25a33SEduard Zingerman r3 = 4096; \
135*efe25a33SEduard Zingerman r2 = r10; \
136*efe25a33SEduard Zingerman r2 += -8; \
137*efe25a33SEduard Zingerman *(u64*)(r2 + 0) = r0; \
138*efe25a33SEduard Zingerman lock *(u64 *)(r2 + 0) += r3; \
139*efe25a33SEduard Zingerman r0 = *(u64*)(r2 + 0); \
140*efe25a33SEduard Zingerman r1 = 22; \
141*efe25a33SEduard Zingerman *(u64*)(r0 + 0) = r1; \
142*efe25a33SEduard Zingerman l0_%=: exit; \
143*efe25a33SEduard Zingerman " :
144*efe25a33SEduard Zingerman : __imm(bpf_map_lookup_elem),
145*efe25a33SEduard Zingerman __imm_addr(map_hash_48b)
146*efe25a33SEduard Zingerman : __clobber_all);
147*efe25a33SEduard Zingerman }
148*efe25a33SEduard Zingerman
149*efe25a33SEduard Zingerman char _license[] SEC("license") = "GPL";
150