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