@@ -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