2 "variable-offset ctx access",
4 /* Get an unknown value */
5 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
6 /* Make it small and 4-byte aligned */
7 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
8 /* add it to skb. We now have either &skb->len or
9 * &skb->pkt_type, but we don't know which
11 BPF_ALU64_REG(BPF_ADD
, BPF_REG_1
, BPF_REG_2
),
13 BPF_LDX_MEM(BPF_W
, BPF_REG_0
, BPF_REG_1
, 0),
16 .errstr
= "variable ctx access var_off=(0x0; 0x4)",
18 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
21 "variable-offset stack access",
23 /* Fill the top 8 bytes of the stack */
24 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
25 /* Get an unknown value */
26 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
27 /* Make it small and 4-byte aligned */
28 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
29 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 8),
30 /* add it to fp. We now have either fp-4 or fp-8, but
33 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
35 BPF_LDX_MEM(BPF_W
, BPF_REG_0
, BPF_REG_2
, 0),
38 .errstr
= "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
40 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
43 "indirect variable-offset stack access, unbounded",
45 BPF_MOV64_IMM(BPF_REG_2
, 6),
46 BPF_MOV64_IMM(BPF_REG_3
, 28),
47 /* Fill the top 16 bytes of the stack. */
48 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -16, 0),
49 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
50 /* Get an unknown value. */
51 BPF_LDX_MEM(BPF_DW
, BPF_REG_4
, BPF_REG_1
, offsetof(struct bpf_sock_ops
,
53 /* Check the lower bound but don't check the upper one. */
54 BPF_JMP_IMM(BPF_JSLT
, BPF_REG_4
, 0, 4),
55 /* Point the lower bound to initialized stack. Offset is now in range
56 * from fp-16 to fp+0x7fffffffffffffef, i.e. max value is unbounded.
58 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_4
, 16),
59 BPF_ALU64_REG(BPF_ADD
, BPF_REG_4
, BPF_REG_10
),
60 BPF_MOV64_IMM(BPF_REG_5
, 8),
61 /* Dereference it indirectly. */
62 BPF_EMIT_CALL(BPF_FUNC_getsockopt
),
63 BPF_MOV64_IMM(BPF_REG_0
, 0),
66 .errstr
= "R4 unbounded indirect variable offset stack access",
68 .prog_type
= BPF_PROG_TYPE_SOCK_OPS
,
71 "indirect variable-offset stack access, max out of bound",
73 /* Fill the top 8 bytes of the stack */
74 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
75 /* Get an unknown value */
76 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
77 /* Make it small and 4-byte aligned */
78 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
79 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 8),
80 /* add it to fp. We now have either fp-4 or fp-8, but
83 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
84 /* dereference it indirectly */
85 BPF_LD_MAP_FD(BPF_REG_1
, 0),
86 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_map_lookup_elem
),
87 BPF_MOV64_IMM(BPF_REG_0
, 0),
90 .fixup_map_hash_8b
= { 5 },
91 .errstr
= "R2 max value is outside of stack bound",
93 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
96 "indirect variable-offset stack access, min out of bound",
98 /* Fill the top 8 bytes of the stack */
99 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
100 /* Get an unknown value */
101 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
102 /* Make it small and 4-byte aligned */
103 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
104 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 516),
105 /* add it to fp. We now have either fp-516 or fp-512, but
106 * we don't know which
108 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
109 /* dereference it indirectly */
110 BPF_LD_MAP_FD(BPF_REG_1
, 0),
111 BPF_RAW_INSN(BPF_JMP
| BPF_CALL
, 0, 0, 0, BPF_FUNC_map_lookup_elem
),
112 BPF_MOV64_IMM(BPF_REG_0
, 0),
115 .fixup_map_hash_8b
= { 5 },
116 .errstr
= "R2 min value is outside of stack bound",
118 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
121 "indirect variable-offset stack access, max_off+size > max_initialized",
123 /* Fill only the second from top 8 bytes of the stack. */
124 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -16, 0),
125 /* Get an unknown value. */
126 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
127 /* Make it small and 4-byte aligned. */
128 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
129 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 16),
130 /* Add it to fp. We now have either fp-12 or fp-16, but we don't know
131 * which. fp-12 size 8 is partially uninitialized stack.
133 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
134 /* Dereference it indirectly. */
135 BPF_LD_MAP_FD(BPF_REG_1
, 0),
136 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem
),
137 BPF_MOV64_IMM(BPF_REG_0
, 0),
140 .fixup_map_hash_8b
= { 5 },
141 .errstr
= "invalid indirect read from stack var_off",
143 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
146 "indirect variable-offset stack access, min_off < min_initialized",
148 /* Fill only the top 8 bytes of the stack. */
149 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
150 /* Get an unknown value */
151 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
152 /* Make it small and 4-byte aligned. */
153 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
154 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 16),
155 /* Add it to fp. We now have either fp-12 or fp-16, but we don't know
156 * which. fp-16 size 8 is partially uninitialized stack.
158 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
159 /* Dereference it indirectly. */
160 BPF_LD_MAP_FD(BPF_REG_1
, 0),
161 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem
),
162 BPF_MOV64_IMM(BPF_REG_0
, 0),
165 .fixup_map_hash_8b
= { 5 },
166 .errstr
= "invalid indirect read from stack var_off",
168 .prog_type
= BPF_PROG_TYPE_LWT_IN
,
171 "indirect variable-offset stack access, priv vs unpriv",
173 /* Fill the top 16 bytes of the stack. */
174 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -16, 0),
175 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
176 /* Get an unknown value. */
177 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
178 /* Make it small and 4-byte aligned. */
179 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
180 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 16),
181 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
182 * which, but either way it points to initialized stack.
184 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
185 /* Dereference it indirectly. */
186 BPF_LD_MAP_FD(BPF_REG_1
, 0),
187 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem
),
188 BPF_MOV64_IMM(BPF_REG_0
, 0),
191 .fixup_map_hash_8b
= { 6 },
192 .errstr_unpriv
= "R2 stack pointer arithmetic goes out of range, prohibited for !root",
193 .result_unpriv
= REJECT
,
195 .prog_type
= BPF_PROG_TYPE_CGROUP_SKB
,
198 "indirect variable-offset stack access, uninitialized",
200 BPF_MOV64_IMM(BPF_REG_2
, 6),
201 BPF_MOV64_IMM(BPF_REG_3
, 28),
202 /* Fill the top 16 bytes of the stack. */
203 BPF_ST_MEM(BPF_W
, BPF_REG_10
, -16, 0),
204 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
205 /* Get an unknown value. */
206 BPF_LDX_MEM(BPF_W
, BPF_REG_4
, BPF_REG_1
, 0),
207 /* Make it small and 4-byte aligned. */
208 BPF_ALU64_IMM(BPF_AND
, BPF_REG_4
, 4),
209 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_4
, 16),
210 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
211 * which, but either way it points to initialized stack.
213 BPF_ALU64_REG(BPF_ADD
, BPF_REG_4
, BPF_REG_10
),
214 BPF_MOV64_IMM(BPF_REG_5
, 8),
215 /* Dereference it indirectly. */
216 BPF_EMIT_CALL(BPF_FUNC_getsockopt
),
217 BPF_MOV64_IMM(BPF_REG_0
, 0),
220 .errstr
= "invalid indirect read from stack var_off",
222 .prog_type
= BPF_PROG_TYPE_SOCK_OPS
,
225 "indirect variable-offset stack access, ok",
227 /* Fill the top 16 bytes of the stack. */
228 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -16, 0),
229 BPF_ST_MEM(BPF_DW
, BPF_REG_10
, -8, 0),
230 /* Get an unknown value. */
231 BPF_LDX_MEM(BPF_W
, BPF_REG_2
, BPF_REG_1
, 0),
232 /* Make it small and 4-byte aligned. */
233 BPF_ALU64_IMM(BPF_AND
, BPF_REG_2
, 4),
234 BPF_ALU64_IMM(BPF_SUB
, BPF_REG_2
, 16),
235 /* Add it to fp. We now have either fp-12 or fp-16, we don't know
236 * which, but either way it points to initialized stack.
238 BPF_ALU64_REG(BPF_ADD
, BPF_REG_2
, BPF_REG_10
),
239 /* Dereference it indirectly. */
240 BPF_LD_MAP_FD(BPF_REG_1
, 0),
241 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem
),
242 BPF_MOV64_IMM(BPF_REG_0
, 0),
245 .fixup_map_hash_8b
= { 6 },
247 .prog_type
= BPF_PROG_TYPE_LWT_IN
,