projects/linux·blob master · refs

143 lines · 3.2 KiB

1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/basic_stack.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include "bpf_misc.h"
7
8struct {
9 __uint(type, BPF_MAP_TYPE_HASH);
10 __uint(max_entries, 1);
11 __type(key, long long);
12 __type(value, long long);
13} map_hash_8b SEC(".maps");
14
15SEC("socket")
16__description("stack out of bounds")
17__failure __msg("invalid write to stack")
18__failure_unpriv
19__naked void stack_out_of_bounds(void)
20{
21 asm volatile (" \
22 r1 = 0; \
23 *(u64*)(r10 + 8) = r1; \
24 exit; \
25" ::: __clobber_all);
26}
27
28SEC("socket")
29__description("uninitialized stack1")
30__success __log_level(4)
31__msg("subprog 0 (uninitialized_stack1) main {{.*}} stack 8")
32__failure_unpriv __msg_unpriv("invalid read from stack")
33__naked void uninitialized_stack1(void)
34{
35 asm volatile (" \
36 r2 = r10; \
37 r2 += -8; \
38 r1 = %[map_hash_8b] ll; \
39 call %[bpf_map_lookup_elem]; \
40 exit; \
41" :
42 : __imm(bpf_map_lookup_elem),
43 __imm_addr(map_hash_8b)
44 : __clobber_all);
45}
46
47SEC("socket")
48__description("uninitialized stack2")
49__success __log_level(4)
50__msg("subprog 0 (uninitialized_stack2) main insns_self {{[0-9]+}} insns_total {{[0-9]+}} stack 8")
51__failure_unpriv __msg_unpriv("invalid read from stack")
52__naked void uninitialized_stack2(void)
53{
54 asm volatile (" \
55 r2 = r10; \
56 r0 = *(u64*)(r2 - 8); \
57 exit; \
58" ::: __clobber_all);
59}
60
61SEC("socket")
62__description("invalid fp arithmetic")
63__failure __msg("R1 subtraction from stack pointer")
64__failure_unpriv
65__naked void invalid_fp_arithmetic(void)
66{
67 /* If this gets ever changed, make sure JITs can deal with it. */
68 asm volatile (" \
69 r0 = 0; \
70 r1 = r10; \
71 r1 -= 8; \
72 *(u64*)(r1 + 0) = r0; \
73 exit; \
74" ::: __clobber_all);
75}
76
77SEC("socket")
78__description("non-invalid fp arithmetic")
79__success __success_unpriv __retval(0)
80__naked void non_invalid_fp_arithmetic(void)
81{
82 asm volatile (" \
83 r0 = 0; \
84 *(u64*)(r10 - 8) = r0; \
85 exit; \
86" ::: __clobber_all);
87}
88
89SEC("socket")
90__description("misaligned read from stack")
91__failure __msg("misaligned stack access")
92__failure_unpriv
93__naked void misaligned_read_from_stack(void)
94{
95 asm volatile (" \
96 r2 = r10; \
97 r0 = *(u64*)(r2 - 4); \
98 exit; \
99" ::: __clobber_all);
100}
101
102SEC("socket")
103__description("stack pointer arithmetic preserves frame number")
104__failure __msg("R7 invalid mem access 'scalar'")
105__naked void stack_ptr_arith_preserves_frameno(void)
106{
107 asm volatile ("\
108 r3 = 0; \
109 *(u64 *)(r10 - 8) = r3; \
110 r1 = %[map_hash_8b] ll; \
111 r2 = r10; \
112 r2 += -8; \
113 call %[bpf_map_lookup_elem]; \
114 if r0 != 0 goto +2; \
115 r0 = 0; \
116 exit; \
117 r1 = r0; \
118 r2 = 0; \
119 r3 = 0; \
120 call stack_ptr_arith_preserves_frameno_subprog;\
121 r0 = 0; \
122 exit; \
123 ":
124 : __imm(bpf_map_lookup_elem),
125 __imm_addr(map_hash_8b)
126 : __clobber_all);
127}
128
129static __used __naked void stack_ptr_arith_preserves_frameno_subprog(void)
130{
131 asm volatile ("\
132 *(u64 *)(r10 - 8) = r1; \
133 r6 = -8; \
134 r6 += r10; \
135 *(u64 *)(r6 + 0) = r2; \
136 r7 = *(u64 *)(r10 - 8); \
137 *(u64 *)(r7 + 0) = r3; \
138 r0 = 0; \
139 exit; \
140 "::: __clobber_all);
141}
142
143char _license[] SEC("license") = "GPL";