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
10struct test_val {
11 unsigned int index;
12 int foo[MAX_ENTRIES];
13};
14
15struct {
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
22SEC("socket")
23__description("map element value illegal alu op, 1")
24__failure __msg("R0 bitwise operator &= on pointer")
25__failure_unpriv
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; \
39l0_%=: exit; \
40" :
41 : __imm(bpf_map_lookup_elem),
42 __imm_addr(map_hash_48b)
43 : __clobber_all);
44}
45
46SEC("socket")
47__description("map element value illegal alu op, 2")
48__failure __msg("R0 32-bit pointer arithmetic prohibited")
49__failure_unpriv
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; \
63l0_%=: exit; \
64" :
65 : __imm(bpf_map_lookup_elem),
66 __imm_addr(map_hash_48b)
67 : __clobber_all);
68}
69
70SEC("socket")
71__description("map element value illegal alu op, 3")
72__failure __msg("R0 pointer arithmetic with /= operator")
73__failure_unpriv
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; \
87l0_%=: exit; \
88" :
89 : __imm(bpf_map_lookup_elem),
90 __imm_addr(map_hash_48b)
91 : __clobber_all);
92}
93
94SEC("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")
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; \
112l0_%=: exit; \
113" :
114 : __imm(bpf_map_lookup_elem),
115 __imm_addr(map_hash_48b)
116 : __clobber_all);
117}
118
119SEC("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")
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; \
142l0_%=: exit; \
143" :
144 : __imm(bpf_map_lookup_elem),
145 __imm_addr(map_hash_48b)
146 : __clobber_all);
147}
148
149SEC("flow_dissector")
150__description("flow_keys illegal alu op with variable offset")
151__failure __msg("R7 pointer arithmetic on flow_keys prohibited")
152__naked void flow_keys_illegal_variable_offset_alu(void)
153{
154 asm volatile(" \
155 r6 = r1; \
156 r7 = *(u64*)(r6 + %[flow_keys_off]); \
157 r8 = 8; \
158 r8 /= 1; \
159 r8 &= 8; \
160 r7 += r8; \
161 r0 = *(u64*)(r7 + 0); \
162 exit; \
163" :
164 : __imm_const(flow_keys_off, offsetof(struct __sk_buff, flow_keys))
165 : __clobber_all);
166}
167
168char _license[] SEC("license") = "GPL";
169

source code of linux/tools/testing/selftests/bpf/progs/verifier_value_illegal_alu.c