@@ -17805,6 +17805,22 @@ static int mark_fastcall_patterns(struct bpf_verifier_env *env)
1780517805	return 0;
1780617806}
1780717807
17808+ static struct bpf_iarray *iarray_realloc(struct bpf_iarray *old, size_t n_elem)
17809+ {
17810+ 	size_t new_size = sizeof(struct bpf_iarray) + n_elem * sizeof(old->items[0]);
17811+ 	struct bpf_iarray *new;
17812+ 
17813+ 	new = kvrealloc(old, new_size, GFP_KERNEL_ACCOUNT);
17814+ 	if (!new) {
17815+ 		/* this is what callers always want, so simplify the call site */
17816+ 		kvfree(old);
17817+ 		return NULL;
17818+ 	}
17819+ 
17820+ 	new->cnt = n_elem;
17821+ 	return new;
17822+ }
17823+ 
1780817824/* Visits the instruction at index t and returns one of the following:
1780917825 *  < 0 - an error occurred
1781017826 *  DONE_EXPLORING - the instruction was fully explored
@@ -18025,8 +18041,9 @@ static int check_cfg(struct bpf_verifier_env *env)
1802518041 */
1802618042static int compute_postorder(struct bpf_verifier_env *env)
1802718043{
18028- 	u32 cur_postorder, i, top, stack_sz, s, succ_cnt, succ[2] ;
18044+ 	u32 cur_postorder, i, top, stack_sz, s;
1802918045	int *stack = NULL, *postorder = NULL, *state = NULL;
18046+ 	struct bpf_iarray *succ;
1803018047
1803118048	postorder = kvcalloc(env->prog->len, sizeof(int), GFP_KERNEL_ACCOUNT);
1803218049	state = kvcalloc(env->prog->len, sizeof(int), GFP_KERNEL_ACCOUNT);
@@ -18050,11 +18067,11 @@ static int compute_postorder(struct bpf_verifier_env *env)
1805018067				stack_sz--;
1805118068				continue;
1805218069			}
18053- 			succ_cnt  = bpf_insn_successors(env->prog , top, succ );
18054- 			for (s = 0; s < succ_cnt ; ++s) {
18055- 				if (!state[succ[s]]) {
18056- 					stack[stack_sz++] = succ[s];
18057- 					state[succ[s]] |= DISCOVERED;
18070+ 			succ  = bpf_insn_successors(env, top);
18071+ 			for (s = 0; s < succ->cnt ; ++s) {
18072+ 				if (!state[succ->items [s]]) {
18073+ 					stack[stack_sz++] = succ->items [s];
18074+ 					state[succ->items [s]] |= DISCOVERED;
1805818075				}
1805918076			}
1806018077			state[top] |= EXPLORED;
@@ -24313,14 +24330,13 @@ static int compute_live_registers(struct bpf_verifier_env *env)
2431324330		for (i = 0; i < env->cfg.cur_postorder; ++i) {
2431424331			int insn_idx = env->cfg.insn_postorder[i];
2431524332			struct insn_live_regs *live = &state[insn_idx];
24316- 			int succ_num;
24317- 			u32 succ[2];
24333+ 			struct bpf_iarray *succ;
2431824334			u16 new_out = 0;
2431924335			u16 new_in = 0;
2432024336
24321- 			succ_num  = bpf_insn_successors(env->prog , insn_idx, succ );
24322- 			for (int s = 0; s < succ_num ; ++s)
24323- 				new_out |= state[succ[s]].in;
24337+ 			succ  = bpf_insn_successors(env, insn_idx);
24338+ 			for (int s = 0; s < succ->cnt ; ++s)
24339+ 				new_out |= state[succ->items [s]].in;
2432424340			new_in = (new_out & ~live->def) | live->use;
2432524341			if (new_out != live->out || new_in != live->in) {
2432624342				live->in = new_in;
@@ -24373,11 +24389,11 @@ static int compute_scc(struct bpf_verifier_env *env)
2437324389	const u32 insn_cnt = env->prog->len;
2437424390	int stack_sz, dfs_sz, err = 0;
2437524391	u32 *stack, *pre, *low, *dfs;
24376- 	u32 succ_cnt,  i, j, t, w;
24392+ 	u32 i, j, t, w;
2437724393	u32 next_preorder_num;
2437824394	u32 next_scc_id;
2437924395	bool assign_scc;
24380- 	u32  succ[2] ;
24396+ 	struct bpf_iarray * succ;
2438124397
2438224398	next_preorder_num = 1;
2438324399	next_scc_id = 1;
@@ -24484,12 +24500,12 @@ static int compute_scc(struct bpf_verifier_env *env)
2448424500				stack[stack_sz++] = w;
2448524501			}
2448624502			/* Visit 'w' successors */
24487- 			succ_cnt  = bpf_insn_successors(env->prog , w, succ );
24488- 			for (j = 0; j < succ_cnt ; ++j) {
24489- 				if (pre[succ[j]]) {
24490- 					low[w] = min(low[w], low[succ[j]]);
24503+ 			succ  = bpf_insn_successors(env, w);
24504+ 			for (j = 0; j < succ->cnt ; ++j) {
24505+ 				if (pre[succ->items [j]]) {
24506+ 					low[w] = min(low[w], low[succ->items [j]]);
2449124507				} else {
24492- 					dfs[dfs_sz++] = succ[j];
24508+ 					dfs[dfs_sz++] = succ->items [j];
2449324509					goto dfs_continue;
2449424510				}
2449524511			}
@@ -24506,8 +24522,8 @@ static int compute_scc(struct bpf_verifier_env *env)
2450624522			 * or if component has a self reference.
2450724523			 */
2450824524			assign_scc = stack[stack_sz - 1] != w;
24509- 			for (j = 0; j < succ_cnt ; ++j) {
24510- 				if (succ[j] == w) {
24525+ 			for (j = 0; j < succ->cnt ; ++j) {
24526+ 				if (succ->items [j] == w) {
2451124527					assign_scc = true;
2451224528					break;
2451324529				}
@@ -24569,6 +24585,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2456924585		goto err_free_env;
2457024586	for (i = 0; i < len; i++)
2457124587		env->insn_aux_data[i].orig_idx = i;
24588+ 	env->succ = iarray_realloc(NULL, 2);
24589+ 	if (!env->succ)
24590+ 		goto err_free_env;
2457224591	env->prog = *prog;
2457324592	env->ops = bpf_verifier_ops[env->prog->type];
2457424593
@@ -24817,6 +24836,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2481724836	bpf_stack_liveness_free(env);
2481824837	kvfree(env->cfg.insn_postorder);
2481924838	kvfree(env->scc_info);
24839+ 	kvfree(env->succ);
2482024840	kvfree(env);
2482124841	return ret;
2482224842}
0 commit comments