xref: /linux/kernel/bpf/cfg.c (revision 2beb1b31a12b57e19cd5c82ea6d54e56520605e8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
3 #include <linux/bpf.h>
4 #include <linux/bpf_verifier.h>
5 #include <linux/filter.h>
6 #include <linux/sort.h>
7 
8 #include "diagnostics.h"
9 
10 #define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args)
11 
12 /* non-recursive DFS pseudo code
13  * 1  procedure DFS-iterative(G,v):
14  * 2      label v as discovered
15  * 3      let S be a stack
16  * 4      S.push(v)
17  * 5      while S is not empty
18  * 6            t <- S.peek()
19  * 7            if t is what we're looking for:
20  * 8                return t
21  * 9            for all edges e in G.adjacentEdges(t) do
22  * 10               if edge e is already labelled
23  * 11                   continue with the next edge
24  * 12               w <- G.adjacentVertex(t,e)
25  * 13               if vertex w is not discovered and not explored
26  * 14                   label e as tree-edge
27  * 15                   label w as discovered
28  * 16                   S.push(w)
29  * 17                   continue at 5
30  * 18               else if vertex w is discovered
31  * 19                   label e as back-edge
32  * 20               else
33  * 21                   // vertex w is explored
34  * 22                   label e as forward- or cross-edge
35  * 23           label t as explored
36  * 24           S.pop()
37  *
38  * convention:
39  * 0x10 - discovered
40  * 0x11 - discovered and fall-through edge labelled
41  * 0x12 - discovered and fall-through and branch edges labelled
42  * 0x20 - explored
43  */
44 
45 enum {
46 	DISCOVERED = 0x10,
47 	EXPLORED = 0x20,
48 	FALLTHROUGH = 1,
49 	BRANCH = 2,
50 };
51 
mark_subprog_changes_pkt_data(struct bpf_verifier_env * env,int off)52 static void mark_subprog_changes_pkt_data(struct bpf_verifier_env *env, int off)
53 {
54 	struct bpf_subprog_info *subprog;
55 
56 	subprog = bpf_find_containing_subprog(env, off);
57 	subprog->changes_pkt_data = true;
58 }
59 
mark_subprog_might_sleep(struct bpf_verifier_env * env,int off)60 static void mark_subprog_might_sleep(struct bpf_verifier_env *env, int off)
61 {
62 	struct bpf_subprog_info *subprog;
63 
64 	subprog = bpf_find_containing_subprog(env, off);
65 	subprog->might_sleep = true;
66 }
67 
mark_subprog_might_throw(struct bpf_verifier_env * env,int off)68 static void mark_subprog_might_throw(struct bpf_verifier_env *env, int off)
69 {
70 	struct bpf_subprog_info *subprog;
71 
72 	subprog = bpf_find_containing_subprog(env, off);
73 	subprog->might_throw = true;
74 }
75 
76 /* 't' is an index of a call-site.
77  * 'w' is a callee entry point.
78  * Eventually this function would be called when env->cfg.insn_state[w] == EXPLORED.
79  * Rely on DFS traversal order and absence of recursive calls to guarantee that
80  * callee's effect marks would be correct at that moment.
81  */
merge_callee_effects(struct bpf_verifier_env * env,int t,int w)82 static void merge_callee_effects(struct bpf_verifier_env *env, int t, int w)
83 {
84 	struct bpf_subprog_info *caller, *callee;
85 
86 	caller = bpf_find_containing_subprog(env, t);
87 	callee = bpf_find_containing_subprog(env, w);
88 	caller->changes_pkt_data |= callee->changes_pkt_data;
89 	caller->might_sleep |= callee->might_sleep;
90 	caller->might_throw |= callee->might_throw;
91 }
92 
93 enum {
94 	DONE_EXPLORING = 0,
95 	KEEP_EXPLORING = 1,
96 };
97 
98 /* t, w, e - match pseudo-code above:
99  * t - index of current instruction
100  * w - next instruction
101  * e - edge
102  */
push_insn(int t,int w,int e,struct bpf_verifier_env * env)103 static int push_insn(int t, int w, int e, struct bpf_verifier_env *env)
104 {
105 	int *insn_stack = env->cfg.insn_stack;
106 	int *insn_state = env->cfg.insn_state;
107 
108 	if (e == FALLTHROUGH && insn_state[t] >= (DISCOVERED | FALLTHROUGH))
109 		return DONE_EXPLORING;
110 
111 	if (e == BRANCH && insn_state[t] >= (DISCOVERED | BRANCH))
112 		return DONE_EXPLORING;
113 
114 	if (w < 0 || w >= env->prog->len) {
115 		verbose_linfo(env, t, "%d: ", t);
116 		verbose(env, "jump out of range from insn %d to %d\n", t, w);
117 		bpf_diag_program_structure(
118 			env, t, "jump out of range", "Keep branch targets inside the program.",
119 			"Instruction %d jumps to instruction %d, but the program only contains instructions 0 through %d.",
120 			t, w, env->prog->len - 1);
121 		return -EINVAL;
122 	}
123 
124 	if (e == BRANCH) {
125 		/* mark branch target for state pruning */
126 		mark_prune_point(env, w);
127 		mark_jmp_point(env, w);
128 		mark_jump_target(env, w);
129 	}
130 
131 	if (insn_state[w] == 0) {
132 		/* tree-edge */
133 		insn_state[t] = DISCOVERED | e;
134 		insn_state[w] = DISCOVERED;
135 		if (env->cfg.cur_stack >= env->prog->len)
136 			return -E2BIG;
137 		insn_stack[env->cfg.cur_stack++] = w;
138 		return KEEP_EXPLORING;
139 	} else if ((insn_state[w] & 0xF0) == DISCOVERED) {
140 		if (env->bpf_capable)
141 			return DONE_EXPLORING;
142 		verbose_linfo(env, t, "%d: ", t);
143 		verbose_linfo(env, w, "%d: ", w);
144 		verbose(env, "back-edge from insn %d to %d\n", t, w);
145 		bpf_diag_program_structure(
146 			env, t, "back-edge is not allowed",
147 			"Load with privileges that allow this back-edge, or rewrite the control flow so it does not branch backward.",
148 			"Instruction %d branches back to instruction %d. This program is being rejected without the privilege needed for this back-edge.",
149 			t, w);
150 		return -EINVAL;
151 	} else if (insn_state[w] == EXPLORED) {
152 		/* forward- or cross-edge */
153 		insn_state[t] = DISCOVERED | e;
154 	} else {
155 		verifier_bug(env, "insn state internal bug");
156 		return -EFAULT;
157 	}
158 	return DONE_EXPLORING;
159 }
160 
visit_func_call_insn(int t,struct bpf_insn * insns,struct bpf_verifier_env * env,bool visit_callee)161 static int visit_func_call_insn(int t, struct bpf_insn *insns,
162 				struct bpf_verifier_env *env,
163 				bool visit_callee)
164 {
165 	int ret, insn_sz;
166 	int w;
167 
168 	insn_sz = bpf_is_ldimm64(&insns[t]) ? 2 : 1;
169 	ret = push_insn(t, t + insn_sz, FALLTHROUGH, env);
170 	if (ret)
171 		return ret;
172 
173 	mark_prune_point(env, t + insn_sz);
174 	/* when we exit from subprog, we need to record non-linear history */
175 	mark_jmp_point(env, t + insn_sz);
176 
177 	if (visit_callee) {
178 		w = t + insns[t].imm + 1;
179 		mark_prune_point(env, t);
180 		merge_callee_effects(env, t, w);
181 		ret = push_insn(t, w, BRANCH, env);
182 	}
183 	return ret;
184 }
185 
bpf_iarray_realloc(struct bpf_iarray * old,size_t n_elem)186 struct bpf_iarray *bpf_iarray_realloc(struct bpf_iarray *old, size_t n_elem)
187 {
188 	size_t new_size = sizeof(struct bpf_iarray) + n_elem * sizeof(old->items[0]);
189 	struct bpf_iarray *new;
190 
191 	new = kvrealloc(old, new_size, GFP_KERNEL_ACCOUNT);
192 	if (!new) {
193 		/* this is what callers always want, so simplify the call site */
194 		kvfree(old);
195 		return NULL;
196 	}
197 
198 	new->cnt = n_elem;
199 	return new;
200 }
201 
copy_insn_array(struct bpf_map * map,u32 start,u32 end,u32 * items)202 static int copy_insn_array(struct bpf_map *map, u32 start, u32 end, u32 *items)
203 {
204 	struct bpf_insn_array_value *value;
205 	u32 i;
206 
207 	for (i = start; i <= end; i++) {
208 		value = map->ops->map_lookup_elem(map, &i);
209 		/*
210 		 * map_lookup_elem of an array map will never return an error,
211 		 * but not checking it makes some static analysers to worry
212 		 */
213 		if (IS_ERR(value))
214 			return PTR_ERR(value);
215 		else if (!value)
216 			return -EINVAL;
217 		items[i - start] = value->xlated_off;
218 	}
219 	return 0;
220 }
221 
cmp_ptr_to_u32(const void * a,const void * b)222 static int cmp_ptr_to_u32(const void *a, const void *b)
223 {
224 	return *(u32 *)a - *(u32 *)b;
225 }
226 
sort_insn_array_uniq(u32 * items,int cnt)227 static int sort_insn_array_uniq(u32 *items, int cnt)
228 {
229 	int unique = 1;
230 	int i;
231 
232 	sort(items, cnt, sizeof(items[0]), cmp_ptr_to_u32, NULL);
233 
234 	for (i = 1; i < cnt; i++)
235 		if (items[i] != items[unique - 1])
236 			items[unique++] = items[i];
237 
238 	return unique;
239 }
240 
241 /*
242  * sort_unique({map[start], ..., map[end]}) into off
243  */
bpf_copy_insn_array_uniq(struct bpf_map * map,u32 start,u32 end,u32 * off)244 int bpf_copy_insn_array_uniq(struct bpf_map *map, u32 start, u32 end, u32 *off)
245 {
246 	u32 n = end - start + 1;
247 	int err;
248 
249 	err = copy_insn_array(map, start, end, off);
250 	if (err)
251 		return err;
252 
253 	return sort_insn_array_uniq(off, n);
254 }
255 
256 /*
257  * Copy all unique offsets from the map
258  */
jt_from_map(struct bpf_map * map)259 static struct bpf_iarray *jt_from_map(struct bpf_map *map)
260 {
261 	struct bpf_iarray *jt;
262 	int err;
263 	int n;
264 
265 	jt = bpf_iarray_realloc(NULL, map->max_entries);
266 	if (!jt)
267 		return ERR_PTR(-ENOMEM);
268 
269 	n = bpf_copy_insn_array_uniq(map, 0, map->max_entries - 1, jt->items);
270 	if (n < 0) {
271 		err = n;
272 		goto err_free;
273 	}
274 	if (n == 0) {
275 		err = -EINVAL;
276 		goto err_free;
277 	}
278 	jt->cnt = n;
279 	return jt;
280 
281 err_free:
282 	kvfree(jt);
283 	return ERR_PTR(err);
284 }
285 
286 /*
287  * Find and collect all maps which fit in the subprog. Return the result as one
288  * combined jump table in jt->items (allocated with kvcalloc)
289  */
jt_from_subprog(struct bpf_verifier_env * env,int subprog_start,int subprog_end)290 static struct bpf_iarray *jt_from_subprog(struct bpf_verifier_env *env,
291 					  int subprog_start, int subprog_end)
292 {
293 	struct bpf_iarray *jt = NULL;
294 	struct bpf_map *map;
295 	struct bpf_iarray *jt_cur;
296 	int i;
297 
298 	for (i = 0; i < env->insn_array_map_cnt; i++) {
299 		/*
300 		 * TODO (when needed): collect only jump tables, not static keys
301 		 * or maps for indirect calls
302 		 */
303 		map = env->insn_array_maps[i];
304 
305 		jt_cur = jt_from_map(map);
306 		if (IS_ERR(jt_cur)) {
307 			kvfree(jt);
308 			return jt_cur;
309 		}
310 
311 		/*
312 		 * This is enough to check one element. The full table is
313 		 * checked to fit inside the subprog later in create_jt()
314 		 */
315 		if (jt_cur->items[0] >= subprog_start && jt_cur->items[0] < subprog_end) {
316 			u32 old_cnt = jt ? jt->cnt : 0;
317 			jt = bpf_iarray_realloc(jt, old_cnt + jt_cur->cnt);
318 			if (!jt) {
319 				kvfree(jt_cur);
320 				return ERR_PTR(-ENOMEM);
321 			}
322 			memcpy(jt->items + old_cnt, jt_cur->items, jt_cur->cnt << 2);
323 		}
324 
325 		kvfree(jt_cur);
326 	}
327 
328 	if (!jt) {
329 		verbose(env, "no jump tables found for subprog starting at %u\n", subprog_start);
330 		bpf_diag_program_structure(
331 			env, subprog_start, "missing jump table",
332 			"Make sure subprograms containing gotox instructions are accompanied by jump tables referencing these subprograms.",
333 			"No jump table was found for the subprogram that starts at instruction %u.",
334 			subprog_start);
335 		return ERR_PTR(-EINVAL);
336 	}
337 
338 	jt->cnt = sort_insn_array_uniq(jt->items, jt->cnt);
339 	return jt;
340 }
341 
342 static struct bpf_iarray *
create_jt(int t,struct bpf_verifier_env * env)343 create_jt(int t, struct bpf_verifier_env *env)
344 {
345 	struct bpf_subprog_info *subprog;
346 	int subprog_start, subprog_end;
347 	struct bpf_iarray *jt;
348 	int i;
349 
350 	subprog = bpf_find_containing_subprog(env, t);
351 	subprog_start = subprog->start;
352 	subprog_end = (subprog + 1)->start;
353 	jt = jt_from_subprog(env, subprog_start, subprog_end);
354 	if (IS_ERR(jt))
355 		return jt;
356 
357 	/* Check that the every element of the jump table fits within the given subprogram */
358 	for (i = 0; i < jt->cnt; i++) {
359 		if (jt->items[i] < subprog_start || jt->items[i] >= subprog_end) {
360 			verbose(env, "jump table for insn %d points outside of the subprog [%u,%u]\n",
361 					t, subprog_start, subprog_end);
362 			bpf_diag_program_structure(
363 				env, t, "jump table target out of range",
364 				"Keep every jump-table target inside the same subprogram.",
365 				"The jump table for instruction %d points outside subprogram range [%u,%u).",
366 				t, subprog_start, subprog_end);
367 			kvfree(jt);
368 			return ERR_PTR(-EINVAL);
369 		}
370 	}
371 
372 	return jt;
373 }
374 
375 /* "conditional jump with N edges" */
visit_gotox_insn(int t,struct bpf_verifier_env * env)376 static int visit_gotox_insn(int t, struct bpf_verifier_env *env)
377 {
378 	int *insn_stack = env->cfg.insn_stack;
379 	int *insn_state = env->cfg.insn_state;
380 	bool keep_exploring = false;
381 	struct bpf_iarray *jt;
382 	int i, w;
383 
384 	jt = env->insn_aux_data[t].jt;
385 	if (!jt) {
386 		jt = create_jt(t, env);
387 		if (IS_ERR(jt))
388 			return PTR_ERR(jt);
389 
390 		env->insn_aux_data[t].jt = jt;
391 	}
392 
393 	mark_prune_point(env, t);
394 	for (i = 0; i < jt->cnt; i++) {
395 		w = jt->items[i];
396 		if (w < 0 || w >= env->prog->len) {
397 			verbose(env, "indirect jump out of range from insn %d to %d\n", t, w);
398 			bpf_diag_program_structure(
399 				env, t, "indirect jump out of range",
400 				"Keep indirect jump targets inside the program.",
401 				"Instruction %d can jump indirectly to instruction %d, but the program only contains instructions 0 through %d.",
402 				t, w, env->prog->len - 1);
403 			return -EINVAL;
404 		}
405 
406 		mark_jmp_point(env, w);
407 		mark_jump_target(env, w);
408 
409 		/* EXPLORED || DISCOVERED */
410 		if (insn_state[w])
411 			continue;
412 
413 		if (env->cfg.cur_stack >= env->prog->len)
414 			return -E2BIG;
415 
416 		insn_stack[env->cfg.cur_stack++] = w;
417 		insn_state[w] |= DISCOVERED;
418 		keep_exploring = true;
419 	}
420 
421 	return keep_exploring ? KEEP_EXPLORING : DONE_EXPLORING;
422 }
423 
424 /*
425  * Instructions that can abnormally return from a subprog (tail_call
426  * upon success, ld_{abs,ind} upon load failure) have a hidden exit
427  * that the verifier must account for.
428  */
visit_abnormal_return_insn(struct bpf_verifier_env * env,int t)429 static int visit_abnormal_return_insn(struct bpf_verifier_env *env, int t)
430 {
431 	struct bpf_subprog_info *subprog;
432 	struct bpf_iarray *jt;
433 
434 	if (env->insn_aux_data[t].jt)
435 		return 0;
436 
437 	jt = bpf_iarray_realloc(NULL, 2);
438 	if (!jt)
439 		return -ENOMEM;
440 
441 	subprog = bpf_find_containing_subprog(env, t);
442 	jt->items[0] = t + 1;
443 	jt->items[1] = subprog->exit_idx;
444 	env->insn_aux_data[t].jt = jt;
445 	return 0;
446 }
447 
448 /* Visits the instruction at index t and returns one of the following:
449  *  < 0 - an error occurred
450  *  DONE_EXPLORING - the instruction was fully explored
451  *  KEEP_EXPLORING - there is still work to be done before it is fully explored
452  */
visit_insn(int t,struct bpf_verifier_env * env)453 static int visit_insn(int t, struct bpf_verifier_env *env)
454 {
455 	struct bpf_insn *insns = env->prog->insnsi, *insn = &insns[t];
456 	int ret, off, insn_sz;
457 
458 	if (bpf_pseudo_func(insn))
459 		return visit_func_call_insn(t, insns, env, true);
460 
461 	/* All non-branch instructions have a single fall-through edge. */
462 	if (BPF_CLASS(insn->code) != BPF_JMP &&
463 	    BPF_CLASS(insn->code) != BPF_JMP32) {
464 		if (BPF_CLASS(insn->code) == BPF_LD &&
465 		    (BPF_MODE(insn->code) == BPF_ABS ||
466 		     BPF_MODE(insn->code) == BPF_IND)) {
467 			ret = visit_abnormal_return_insn(env, t);
468 			if (ret)
469 				return ret;
470 		}
471 		insn_sz = bpf_is_ldimm64(insn) ? 2 : 1;
472 		return push_insn(t, t + insn_sz, FALLTHROUGH, env);
473 	}
474 
475 	switch (BPF_OP(insn->code)) {
476 	case BPF_EXIT:
477 		return DONE_EXPLORING;
478 
479 	case BPF_CALL:
480 		if (bpf_is_async_callback_calling_insn(insn))
481 			/* Mark this call insn as a prune point to trigger
482 			 * is_state_visited() check before call itself is
483 			 * processed by __check_func_call(). Otherwise new
484 			 * async state will be pushed for further exploration.
485 			 */
486 			mark_prune_point(env, t);
487 		/* For functions that invoke callbacks it is not known how many times
488 		 * callback would be called. Verifier models callback calling functions
489 		 * by repeatedly visiting callback bodies and returning to origin call
490 		 * instruction.
491 		 * In order to stop such iteration verifier needs to identify when a
492 		 * state identical some state from a previous iteration is reached.
493 		 * Check below forces creation of checkpoint before callback calling
494 		 * instruction to allow search for such identical states.
495 		 */
496 		if (bpf_is_sync_callback_calling_insn(insn)) {
497 			mark_calls_callback(env, t);
498 			mark_force_checkpoint(env, t);
499 			mark_prune_point(env, t);
500 			mark_jmp_point(env, t);
501 		}
502 		if (bpf_helper_call(insn)) {
503 			const struct bpf_func_proto *fp;
504 
505 			ret = bpf_get_helper_proto(env, insn->imm, &fp);
506 			/* If called in a non-sleepable context program will be
507 			 * rejected anyway, so we should end up with precise
508 			 * sleepable marks on subprogs, except for dead code
509 			 * elimination.
510 			 */
511 			if (ret == 0 && fp->might_sleep)
512 				mark_subprog_might_sleep(env, t);
513 			if (bpf_helper_changes_pkt_data(insn->imm))
514 				mark_subprog_changes_pkt_data(env, t);
515 			if (insn->imm == BPF_FUNC_tail_call) {
516 				ret = visit_abnormal_return_insn(env, t);
517 				if (ret)
518 					return ret;
519 			}
520 		} else if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
521 			struct bpf_call_arg_meta meta;
522 
523 			ret = bpf_fetch_kfunc_arg_meta(env, insn->imm, insn->off, &meta);
524 			if (ret == 0 && bpf_is_iter_next_kfunc(&meta)) {
525 				mark_prune_point(env, t);
526 				/* Checking and saving state checkpoints at iter_next() call
527 				 * is crucial for fast convergence of open-coded iterator loop
528 				 * logic, so we need to force it. If we don't do that,
529 				 * is_state_visited() might skip saving a checkpoint, causing
530 				 * unnecessarily long sequence of not checkpointed
531 				 * instructions and jumps, leading to exhaustion of jump
532 				 * history buffer, and potentially other undesired outcomes.
533 				 * It is expected that with correct open-coded iterators
534 				 * convergence will happen quickly, so we don't run a risk of
535 				 * exhausting memory.
536 				 */
537 				mark_force_checkpoint(env, t);
538 			}
539 			/* Same as helpers, if called in a non-sleepable context
540 			 * program will be rejected anyway, so we should end up
541 			 * with precise sleepable marks on subprogs, except for
542 			 * dead code elimination.
543 			 */
544 			if (ret == 0 && bpf_is_kfunc_sleepable(&meta))
545 				mark_subprog_might_sleep(env, t);
546 			if (ret == 0 && bpf_is_kfunc_pkt_changing(&meta))
547 				mark_subprog_changes_pkt_data(env, t);
548 			if (ret == 0 && bpf_is_throw_kfunc(insn))
549 				mark_subprog_might_throw(env, t);
550 		}
551 		return visit_func_call_insn(t, insns, env, insn->src_reg == BPF_PSEUDO_CALL);
552 
553 	case BPF_JA:
554 		if (BPF_SRC(insn->code) == BPF_X)
555 			return visit_gotox_insn(t, env);
556 
557 		if (BPF_CLASS(insn->code) == BPF_JMP)
558 			off = insn->off;
559 		else
560 			off = insn->imm;
561 
562 		/* unconditional jump with single edge */
563 		ret = push_insn(t, t + off + 1, FALLTHROUGH, env);
564 		if (ret)
565 			return ret;
566 
567 		mark_prune_point(env, t + off + 1);
568 		mark_jmp_point(env, t + off + 1);
569 		mark_jump_target(env, t + off + 1);
570 
571 		return ret;
572 
573 	default:
574 		/* conditional jump with two edges */
575 		mark_prune_point(env, t);
576 		if (bpf_is_may_goto_insn(insn))
577 			mark_force_checkpoint(env, t);
578 
579 		ret = push_insn(t, t + 1, FALLTHROUGH, env);
580 		if (ret)
581 			return ret;
582 
583 		return push_insn(t, t + insn->off + 1, BRANCH, env);
584 	}
585 }
586 
587 /* non-recursive depth-first-search to detect loops in BPF program
588  * loop == back-edge in directed graph
589  */
bpf_check_cfg(struct bpf_verifier_env * env)590 int bpf_check_cfg(struct bpf_verifier_env *env)
591 {
592 	int insn_cnt = env->prog->len;
593 	int *insn_stack, *insn_state;
594 	int ex_insn_beg, i, ret = 0;
595 
596 	insn_state = env->cfg.insn_state = kvzalloc_objs(int, insn_cnt,
597 							 GFP_KERNEL_ACCOUNT);
598 	if (!insn_state)
599 		return -ENOMEM;
600 
601 	insn_stack = env->cfg.insn_stack = kvzalloc_objs(int, insn_cnt,
602 							 GFP_KERNEL_ACCOUNT);
603 	if (!insn_stack) {
604 		kvfree(insn_state);
605 		return -ENOMEM;
606 	}
607 
608 	ex_insn_beg = env->exception_callback_subprog
609 		      ? env->subprog_info[env->exception_callback_subprog].start
610 		      : 0;
611 
612 	insn_state[0] = DISCOVERED; /* mark 1st insn as discovered */
613 	insn_stack[0] = 0; /* 0 is the first instruction */
614 	env->cfg.cur_stack = 1;
615 
616 walk_cfg:
617 	while (env->cfg.cur_stack > 0) {
618 		int t = insn_stack[env->cfg.cur_stack - 1];
619 
620 		ret = visit_insn(t, env);
621 		switch (ret) {
622 		case DONE_EXPLORING:
623 			insn_state[t] = EXPLORED;
624 			env->cfg.cur_stack--;
625 			break;
626 		case KEEP_EXPLORING:
627 			break;
628 		default:
629 			if (ret > 0) {
630 				verifier_bug(env, "visit_insn internal bug");
631 				ret = -EFAULT;
632 			}
633 			goto err_free;
634 		}
635 	}
636 
637 	if (env->cfg.cur_stack < 0) {
638 		verifier_bug(env, "pop stack internal bug");
639 		ret = -EFAULT;
640 		goto err_free;
641 	}
642 
643 	if (ex_insn_beg && insn_state[ex_insn_beg] != EXPLORED) {
644 		insn_state[ex_insn_beg] = DISCOVERED;
645 		insn_stack[0] = ex_insn_beg;
646 		env->cfg.cur_stack = 1;
647 		goto walk_cfg;
648 	}
649 
650 	for (i = 0; i < insn_cnt; i++) {
651 		struct bpf_insn *insn = &env->prog->insnsi[i];
652 
653 		if (insn_state[i] != EXPLORED) {
654 			verbose(env, "unreachable insn %d\n", i);
655 			bpf_diag_program_structure(
656 				env, i, "unreachable instruction",
657 				"Remove the unreachable instruction or add valid control flow that reaches it.",
658 				"Instruction %d is not reachable from the program entry point.", i);
659 			ret = -EINVAL;
660 			goto err_free;
661 		}
662 		if (bpf_is_ldimm64(insn)) {
663 			if (insn_state[i + 1] != 0) {
664 				verbose(env, "jump into the middle of ldimm64 insn %d\n", i);
665 				bpf_diag_program_structure(
666 					env, i, "jump into ldimm64 immediate",
667 					"Target the first instruction of the ldimm64 pair, or restructure the jump target.",
668 					"Control flow reaches the second half of the ldimm64 instruction pair that starts at instruction %d.",
669 					i);
670 				ret = -EINVAL;
671 				goto err_free;
672 			}
673 			i++; /* skip second half of ldimm64 */
674 		}
675 	}
676 	ret = 0; /* cfg looks good */
677 	env->prog->aux->changes_pkt_data = env->subprog_info[0].changes_pkt_data;
678 	env->prog->aux->might_sleep = env->subprog_info[0].might_sleep;
679 
680 err_free:
681 	kvfree(insn_state);
682 	kvfree(insn_stack);
683 	env->cfg.insn_state = env->cfg.insn_stack = NULL;
684 	return ret;
685 }
686 
687 /*
688  * For each subprogram 'i' fill array env->cfg.insn_subprogram sub-range
689  * [env->subprog_info[i].postorder_start, env->subprog_info[i+1].postorder_start)
690  * with indices of 'i' instructions in postorder.
691  */
bpf_compute_postorder(struct bpf_verifier_env * env)692 int bpf_compute_postorder(struct bpf_verifier_env *env)
693 {
694 	u32 cur_postorder, i, top, stack_sz, s;
695 	int *stack = NULL, *postorder = NULL, *state = NULL;
696 	struct bpf_iarray *succ;
697 
698 	postorder = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT);
699 	state = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT);
700 	stack = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT);
701 	if (!postorder || !state || !stack) {
702 		kvfree(postorder);
703 		kvfree(state);
704 		kvfree(stack);
705 		return -ENOMEM;
706 	}
707 	cur_postorder = 0;
708 	for (i = 0; i < env->subprog_cnt; i++) {
709 		env->subprog_info[i].postorder_start = cur_postorder;
710 		stack[0] = env->subprog_info[i].start;
711 		stack_sz = 1;
712 		do {
713 			top = stack[stack_sz - 1];
714 			state[top] |= DISCOVERED;
715 			if (state[top] & EXPLORED) {
716 				postorder[cur_postorder++] = top;
717 				stack_sz--;
718 				continue;
719 			}
720 			succ = bpf_insn_successors(env, top);
721 			for (s = 0; s < succ->cnt; ++s) {
722 				if (!state[succ->items[s]]) {
723 					stack[stack_sz++] = succ->items[s];
724 					state[succ->items[s]] |= DISCOVERED;
725 				}
726 			}
727 			state[top] |= EXPLORED;
728 		} while (stack_sz);
729 	}
730 	env->subprog_info[i].postorder_start = cur_postorder;
731 	env->cfg.insn_postorder = postorder;
732 	env->cfg.cur_postorder = cur_postorder;
733 	kvfree(stack);
734 	kvfree(state);
735 	return 0;
736 }
737 
738 /*
739  * Compute strongly connected components (SCCs) on the CFG.
740  * Assign an SCC number to each instruction, recorded in env->insn_aux[*].scc.
741  * If instruction is a sole member of its SCC and there are no self edges,
742  * assign it SCC number of zero.
743  * Uses a non-recursive adaptation of Tarjan's algorithm for SCC computation.
744  */
bpf_compute_scc(struct bpf_verifier_env * env)745 int bpf_compute_scc(struct bpf_verifier_env *env)
746 {
747 	const u32 NOT_ON_STACK = U32_MAX;
748 
749 	struct bpf_insn_aux_data *aux = env->insn_aux_data;
750 	const u32 insn_cnt = env->prog->len;
751 	int stack_sz, dfs_sz, err = 0;
752 	u32 *stack, *pre, *low, *dfs;
753 	u32 i, j, t, w;
754 	u32 next_preorder_num;
755 	u32 next_scc_id;
756 	bool assign_scc;
757 	struct bpf_iarray *succ;
758 
759 	next_preorder_num = 1;
760 	next_scc_id = 1;
761 	/*
762 	 * - 'stack' accumulates vertices in DFS order, see invariant comment below;
763 	 * - 'pre[t] == p' => preorder number of vertex 't' is 'p';
764 	 * - 'low[t] == n' => smallest preorder number of the vertex reachable from 't' is 'n';
765 	 * - 'dfs' DFS traversal stack, used to emulate explicit recursion.
766 	 */
767 	stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
768 	pre = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
769 	low = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
770 	dfs = kvcalloc(insn_cnt, sizeof(*dfs), GFP_KERNEL_ACCOUNT);
771 	if (!stack || !pre || !low || !dfs) {
772 		err = -ENOMEM;
773 		goto exit;
774 	}
775 	/*
776 	 * References:
777 	 * [1] R. Tarjan "Depth-First Search and Linear Graph Algorithms"
778 	 * [2] D. J. Pearce "A Space-Efficient Algorithm for Finding Strongly Connected Components"
779 	 *
780 	 * The algorithm maintains the following invariant:
781 	 * - suppose there is a path 'u' ~> 'v', such that 'pre[v] < pre[u]';
782 	 * - then, vertex 'u' remains on stack while vertex 'v' is on stack.
783 	 *
784 	 * Consequently:
785 	 * - If 'low[v] < pre[v]', there is a path from 'v' to some vertex 'u',
786 	 *   such that 'pre[u] == low[v]'; vertex 'u' is currently on the stack,
787 	 *   and thus there is an SCC (loop) containing both 'u' and 'v'.
788 	 * - If 'low[v] == pre[v]', loops containing 'v' have been explored,
789 	 *   and 'v' can be considered the root of some SCC.
790 	 *
791 	 * Here is a pseudo-code for an explicitly recursive version of the algorithm:
792 	 *
793 	 *    NOT_ON_STACK = insn_cnt + 1
794 	 *    pre = [0] * insn_cnt
795 	 *    low = [0] * insn_cnt
796 	 *    scc = [0] * insn_cnt
797 	 *    stack = []
798 	 *
799 	 *    next_preorder_num = 1
800 	 *    next_scc_id = 1
801 	 *
802 	 *    def recur(w):
803 	 *        nonlocal next_preorder_num
804 	 *        nonlocal next_scc_id
805 	 *
806 	 *        pre[w] = next_preorder_num
807 	 *        low[w] = next_preorder_num
808 	 *        next_preorder_num += 1
809 	 *        stack.append(w)
810 	 *        for s in successors(w):
811 	 *            # Note: for classic algorithm the block below should look as:
812 	 *            #
813 	 *            # if pre[s] == 0:
814 	 *            #     recur(s)
815 	 *            #     low[w] = min(low[w], low[s])
816 	 *            # elif low[s] != NOT_ON_STACK:
817 	 *            #     low[w] = min(low[w], pre[s])
818 	 *            #
819 	 *            # But replacing both 'min' instructions with 'low[w] = min(low[w], low[s])'
820 	 *            # does not break the invariant and makes iterative version of the algorithm
821 	 *            # simpler. See 'Algorithm #3' from [2].
822 	 *
823 	 *            # 's' not yet visited
824 	 *            if pre[s] == 0:
825 	 *                recur(s)
826 	 *            # if 's' is on stack, pick lowest reachable preorder number from it;
827 	 *            # if 's' is not on stack 'low[s] == NOT_ON_STACK > low[w]',
828 	 *            # so 'min' would be a noop.
829 	 *            low[w] = min(low[w], low[s])
830 	 *
831 	 *        if low[w] == pre[w]:
832 	 *            # 'w' is the root of an SCC, pop all vertices
833 	 *            # below 'w' on stack and assign same SCC to them.
834 	 *            while True:
835 	 *                t = stack.pop()
836 	 *                low[t] = NOT_ON_STACK
837 	 *                scc[t] = next_scc_id
838 	 *                if t == w:
839 	 *                    break
840 	 *            next_scc_id += 1
841 	 *
842 	 *    for i in range(0, insn_cnt):
843 	 *        if pre[i] == 0:
844 	 *            recur(i)
845 	 *
846 	 * Below implementation replaces explicit recursion with array 'dfs'.
847 	 */
848 	for (i = 0; i < insn_cnt; i++) {
849 		if (pre[i])
850 			continue;
851 		stack_sz = 0;
852 		dfs_sz = 1;
853 		dfs[0] = i;
854 dfs_continue:
855 		while (dfs_sz) {
856 			w = dfs[dfs_sz - 1];
857 			if (pre[w] == 0) {
858 				low[w] = next_preorder_num;
859 				pre[w] = next_preorder_num;
860 				next_preorder_num++;
861 				stack[stack_sz++] = w;
862 			}
863 			/* Visit 'w' successors */
864 			succ = bpf_insn_successors(env, w);
865 			for (j = 0; j < succ->cnt; ++j) {
866 				if (pre[succ->items[j]]) {
867 					low[w] = min(low[w], low[succ->items[j]]);
868 				} else {
869 					dfs[dfs_sz++] = succ->items[j];
870 					goto dfs_continue;
871 				}
872 			}
873 			/*
874 			 * Preserve the invariant: if some vertex above in the stack
875 			 * is reachable from 'w', keep 'w' on the stack.
876 			 */
877 			if (low[w] < pre[w]) {
878 				dfs_sz--;
879 				goto dfs_continue;
880 			}
881 			/*
882 			 * Assign SCC number only if component has two or more elements,
883 			 * or if component has a self reference, or if instruction is a
884 			 * callback calling function (implicit loop).
885 			 */
886 			assign_scc = stack[stack_sz - 1] != w;	/* two or more elements? */
887 			for (j = 0; j < succ->cnt; ++j) {	/* self reference? */
888 				if (succ->items[j] == w) {
889 					assign_scc = true;
890 					break;
891 				}
892 			}
893 			if (bpf_calls_callback(env, w)) /* implicit loop? */
894 				assign_scc = true;
895 			/* Pop component elements from stack */
896 			do {
897 				t = stack[--stack_sz];
898 				low[t] = NOT_ON_STACK;
899 				if (assign_scc)
900 					aux[t].scc = next_scc_id;
901 			} while (t != w);
902 			if (assign_scc)
903 				next_scc_id++;
904 			dfs_sz--;
905 		}
906 	}
907 	env->scc_info = kvzalloc_objs(*env->scc_info, next_scc_id,
908 				      GFP_KERNEL_ACCOUNT);
909 	if (!env->scc_info) {
910 		err = -ENOMEM;
911 		goto exit;
912 	}
913 	env->scc_cnt = next_scc_id;
914 exit:
915 	kvfree(stack);
916 	kvfree(pre);
917 	kvfree(low);
918 	kvfree(dfs);
919 	return err;
920 }
921