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