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