File Index
Files and directories
Sign in
FILE

verifier_value_illegal_alu.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/progs/verifier_value_illegal_alu.c C
  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 "../../../include/linux/filter.h"
  7#include "bpf_misc.h"
  8
  9#define MAX_ENTRIES 11
 10
 11struct test_val {
 12	unsigned int index;
 13	int foo[MAX_ENTRIES];
 14};
 15
 16struct {
 17	__uint(type, BPF_MAP_TYPE_HASH);
 18	__uint(max_entries, 1);
 19	__type(key, long long);
 20	__type(value, struct test_val);
 21} map_hash_48b SEC(".maps");
 22
 23SEC("socket")
 24__description("map element value illegal alu op, 1")
 25__failure __msg("R0 bitwise operator &= on pointer")
 26__failure_unpriv
 27__naked void value_illegal_alu_op_1(void)
 28{
 29	asm volatile ("					\
 30	r2 = r10;					\
 31	r2 += -8;					\
 32	r1 = 0;						\
 33	*(u64*)(r2 + 0) = r1;				\
 34	r1 = %[map_hash_48b] ll;			\
 35	call %[bpf_map_lookup_elem];			\
 36	if r0 == 0 goto l0_%=;				\
 37	r0 &= 8;					\
 38	r1 = 22;					\
 39	*(u64*)(r0 + 0) = r1;				\
 40l0_%=:	exit;						\
 41"	:
 42	: __imm(bpf_map_lookup_elem),
 43	  __imm_addr(map_hash_48b)
 44	: __clobber_all);
 45}
 46
 47SEC("socket")
 48__description("map element value illegal alu op, 2")
 49__failure __msg("R0 32-bit pointer arithmetic prohibited")
 50__failure_unpriv
 51__naked void value_illegal_alu_op_2(void)
 52{
 53	asm volatile ("					\
 54	r2 = r10;					\
 55	r2 += -8;					\
 56	r1 = 0;						\
 57	*(u64*)(r2 + 0) = r1;				\
 58	r1 = %[map_hash_48b] ll;			\
 59	call %[bpf_map_lookup_elem];			\
 60	if r0 == 0 goto l0_%=;				\
 61	w0 += 0;					\
 62	r1 = 22;					\
 63	*(u64*)(r0 + 0) = r1;				\
 64l0_%=:	exit;						\
 65"	:
 66	: __imm(bpf_map_lookup_elem),
 67	  __imm_addr(map_hash_48b)
 68	: __clobber_all);
 69}
 70
 71SEC("socket")
 72__description("map element value illegal alu op, 3")
 73__failure __msg("R0 pointer arithmetic with /= operator")
 74__failure_unpriv
 75__naked void value_illegal_alu_op_3(void)
 76{
 77	asm volatile ("					\
 78	r2 = r10;					\
 79	r2 += -8;					\
 80	r1 = 0;						\
 81	*(u64*)(r2 + 0) = r1;				\
 82	r1 = %[map_hash_48b] ll;			\
 83	call %[bpf_map_lookup_elem];			\
 84	if r0 == 0 goto l0_%=;				\
 85	r0 /= 42;					\
 86	r1 = 22;					\
 87	*(u64*)(r0 + 0) = r1;				\
 88l0_%=:	exit;						\
 89"	:
 90	: __imm(bpf_map_lookup_elem),
 91	  __imm_addr(map_hash_48b)
 92	: __clobber_all);
 93}
 94
 95SEC("socket")
 96__description("map element value illegal alu op, 4")
 97__failure __msg("invalid mem access 'scalar'")
 98__failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited")
 99__flag(BPF_F_ANY_ALIGNMENT)
100__naked void value_illegal_alu_op_4(void)
101{
102	asm volatile ("					\
103	r2 = r10;					\
104	r2 += -8;					\
105	r1 = 0;						\
106	*(u64*)(r2 + 0) = r1;				\
107	r1 = %[map_hash_48b] ll;			\
108	call %[bpf_map_lookup_elem];			\
109	if r0 == 0 goto l0_%=;				\
110	r0 = be64 r0;					\
111	r1 = 22;					\
112	*(u64*)(r0 + 0) = r1;				\
113l0_%=:	exit;						\
114"	:
115	: __imm(bpf_map_lookup_elem),
116	  __imm_addr(map_hash_48b)
117	: __clobber_all);
118}
119
120SEC("socket")
121__description("map element value illegal alu op, 5")
122__failure __msg("R0 invalid mem access 'scalar'")
123__msg_unpriv("leaking pointer from stack off -8")
124__flag(BPF_F_ANY_ALIGNMENT)
125__naked void value_illegal_alu_op_5(void)
126{
127	asm volatile ("					\
128	r2 = r10;					\
129	r2 += -8;					\
130	r1 = 0;						\
131	*(u64*)(r2 + 0) = r1;				\
132	r1 = %[map_hash_48b] ll;			\
133	call %[bpf_map_lookup_elem];			\
134	if r0 == 0 goto l0_%=;				\
135	r3 = 4096;					\
136	r2 = r10;					\
137	r2 += -8;					\
138	*(u64*)(r2 + 0) = r0;				\
139	lock *(u64 *)(r2 + 0) += r3;			\
140	r0 = *(u64*)(r2 + 0);				\
141	r1 = 22;					\
142	*(u64*)(r0 + 0) = r1;				\
143l0_%=:	exit;						\
144"	:
145	: __imm(bpf_map_lookup_elem),
146	  __imm_addr(map_hash_48b)
147	: __clobber_all);
148}
149
150SEC("socket")
151__description("map_ptr illegal alu op, map_ptr = -map_ptr")
152__failure __msg("R0 invalid mem access 'scalar'")
153__failure_unpriv __msg_unpriv("R0 pointer arithmetic prohibited")
154__flag(BPF_F_ANY_ALIGNMENT)
155__naked void map_ptr_illegal_alu_op(void)
156{
157	asm volatile ("					\
158	r0 = %[map_hash_48b] ll;			\
159	r0 = -r0;					\
160	r1 = 22;					\
161	*(u64*)(r0 + 0) = r1;				\
162	exit;						\
163"	:
164	: __imm_addr(map_hash_48b)
165	: __clobber_all);
166}
167
168SEC("flow_dissector")
169__description("flow_keys illegal alu op with variable offset")
170__failure __msg("R7 pointer arithmetic on flow_keys prohibited")
171__naked void flow_keys_illegal_variable_offset_alu(void)
172{
173	asm volatile("					\
174	r6 = r1;					\
175	r7 = *(u64*)(r6 + %[flow_keys_off]);		\
176	r8 = 8;						\
177	r8 /= 1;					\
178	r8 &= 8;					\
179	r7 += r8;					\
180	r0 = *(u64*)(r7 + 0);				\
181	exit;						\
182"	:
183	: __imm_const(flow_keys_off, offsetof(struct __sk_buff, flow_keys))
184	: __clobber_all);
185}
186
187#define DEFINE_BAD_OFFSET_TEST(name, op, off, imm)	\
188	SEC("socket")					\
189	__failure __msg("BPF_ALU uses reserved fields") \
190	__naked void name(void)				\
191	{						\
192		asm volatile(				\
193			"r0 = 1;"			\
194			".8byte %[insn];"		\
195			"r0 = 0;"			\
196			"exit;"				\
197		:					\
198		: __imm_insn(insn, BPF_RAW_INSN((op), 0, 0, (off), (imm))) \
199		: __clobber_all);			\
200	}
201
202/*
203 * Offset fields of 0 and 1 are legal for BPF_{DIV,MOD} instructions.
204 * Offset fields of 0 are legal for the rest of ALU instructions.
205 * Test that error is reported for illegal offsets, assuming that tests
206 * for legal offsets exist.
207 */
208DEFINE_BAD_OFFSET_TEST(bad_offset_divx, BPF_ALU64 | BPF_DIV | BPF_X, -1, 0)
209DEFINE_BAD_OFFSET_TEST(bad_offset_modk, BPF_ALU64 | BPF_MOD | BPF_K, -1, 1)
210DEFINE_BAD_OFFSET_TEST(bad_offset_addx, BPF_ALU64 | BPF_ADD | BPF_X, -1, 0)
211DEFINE_BAD_OFFSET_TEST(bad_offset_divx2, BPF_ALU64 | BPF_DIV | BPF_X, 2, 0)
212DEFINE_BAD_OFFSET_TEST(bad_offset_modk2, BPF_ALU64 | BPF_MOD | BPF_K, 2, 1)
213DEFINE_BAD_OFFSET_TEST(bad_offset_addx2, BPF_ALU64 | BPF_ADD | BPF_X, 1, 0)
214
215char _license[] SEC("license") = "GPL";
~/ Read-only file preview.