@@ -1691,7 +1691,7 @@ static u32 state_htab_size(struct bpf_verifier_env *env)
1691
1691
return env->prog->len;
1692
1692
}
1693
1693
1694
- static struct bpf_verifier_state_list * *explored_state(struct bpf_verifier_env *env, int idx)
1694
+ static struct list_head *explored_state(struct bpf_verifier_env *env, int idx)
1695
1695
{
1696
1696
struct bpf_verifier_state *cur = env->cur_state;
1697
1697
struct bpf_func_state *state = cur->frame[cur->curframe];
@@ -8443,10 +8443,12 @@ static struct bpf_verifier_state *find_prev_entry(struct bpf_verifier_env *env,
8443
8443
{
8444
8444
struct bpf_verifier_state_list *sl;
8445
8445
struct bpf_verifier_state *st;
8446
+ struct list_head *pos, *head;
8446
8447
8447
8448
/* Explored states are pushed in stack order, most recent states come first */
8448
- sl = *explored_state(env, insn_idx);
8449
- for (; sl; sl = sl->next) {
8449
+ head = explored_state(env, insn_idx);
8450
+ list_for_each(pos, head) {
8451
+ sl = container_of(pos, struct bpf_verifier_state_list, node);
8450
8452
/* If st->branches != 0 state is a part of current DFS verification path,
8451
8453
* hence cur & st for a loop.
8452
8454
*/
@@ -17857,20 +17859,20 @@ static void clean_live_states(struct bpf_verifier_env *env, int insn,
17857
17859
{
17858
17860
struct bpf_verifier_state *loop_entry;
17859
17861
struct bpf_verifier_state_list *sl;
17862
+ struct list_head *pos, *head;
17860
17863
17861
- sl = *explored_state(env, insn);
17862
- while (sl) {
17864
+ head = explored_state(env, insn);
17865
+ list_for_each(pos, head) {
17866
+ sl = container_of(pos, struct bpf_verifier_state_list, node);
17863
17867
if (sl->state.branches)
17864
- goto next ;
17868
+ continue ;
17865
17869
loop_entry = get_loop_entry(env, &sl->state);
17866
17870
if (!IS_ERR_OR_NULL(loop_entry) && loop_entry->branches)
17867
- goto next ;
17871
+ continue ;
17868
17872
if (sl->state.insn_idx != insn ||
17869
17873
!same_callsites(&sl->state, cur))
17870
- goto next ;
17874
+ continue ;
17871
17875
clean_verifier_state(env, &sl->state);
17872
- next:
17873
- sl = sl->next;
17874
17876
}
17875
17877
}
17876
17878
@@ -18561,10 +18563,11 @@ static bool iter_active_depths_differ(struct bpf_verifier_state *old, struct bpf
18561
18563
static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
18562
18564
{
18563
18565
struct bpf_verifier_state_list *new_sl;
18564
- struct bpf_verifier_state_list *sl, **pprev ;
18566
+ struct bpf_verifier_state_list *sl;
18565
18567
struct bpf_verifier_state *cur = env->cur_state, *new, *loop_entry;
18566
18568
int i, j, n, err, states_cnt = 0;
18567
18569
bool force_new_state, add_new_state, force_exact;
18570
+ struct list_head *pos, *tmp, *head;
18568
18571
18569
18572
force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx) ||
18570
18573
/* Avoid accumulating infinitely long jmp history */
@@ -18583,15 +18586,14 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
18583
18586
env->insn_processed - env->prev_insn_processed >= 8)
18584
18587
add_new_state = true;
18585
18588
18586
- pprev = explored_state(env, insn_idx);
18587
- sl = *pprev;
18588
-
18589
18589
clean_live_states(env, insn_idx, cur);
18590
18590
18591
- while (sl) {
18591
+ head = explored_state(env, insn_idx);
18592
+ list_for_each_safe(pos, tmp, head) {
18593
+ sl = container_of(pos, struct bpf_verifier_state_list, node);
18592
18594
states_cnt++;
18593
18595
if (sl->state.insn_idx != insn_idx)
18594
- goto next ;
18596
+ continue ;
18595
18597
18596
18598
if (sl->state.branches) {
18597
18599
struct bpf_func_state *frame = sl->state.frame[sl->state.curframe];
@@ -18796,7 +18798,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
18796
18798
/* the state is unlikely to be useful. Remove it to
18797
18799
* speed up verification
18798
18800
*/
18799
- *pprev = sl->next ;
18801
+ list_del(& sl->node) ;
18800
18802
if (sl->state.frame[0]->regs[0].live & REG_LIVE_DONE &&
18801
18803
!sl->state.used_as_loop_entry) {
18802
18804
u32 br = sl->state.branches;
@@ -18812,15 +18814,9 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
18812
18814
* walk it later. Add it for free_list instead to
18813
18815
* be freed at the end of verification
18814
18816
*/
18815
- sl->next = env->free_list;
18816
- env->free_list = sl;
18817
+ list_add(&sl->node, &env->free_list);
18817
18818
}
18818
- sl = *pprev;
18819
- continue;
18820
18819
}
18821
- next:
18822
- pprev = &sl->next;
18823
- sl = *pprev;
18824
18820
}
18825
18821
18826
18822
if (env->max_states_per_insn < states_cnt)
@@ -18869,8 +18865,8 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
18869
18865
cur->first_insn_idx = insn_idx;
18870
18866
cur->insn_hist_start = cur->insn_hist_end;
18871
18867
cur->dfs_depth = new->dfs_depth + 1;
18872
- new_sl->next = *explored_state(env, insn_idx );
18873
- *explored_state(env, insn_idx) = new_sl;
18868
+ list_add(& new_sl->node, head );
18869
+
18874
18870
/* connect new state to parentage chain. Current frame needs all
18875
18871
* registers connected. Only r6 - r9 of the callers are alive (pushed
18876
18872
* to the stack implicitly by JITs) so in callers' frames connect just
@@ -22194,31 +22190,29 @@ static int remove_fastcall_spills_fills(struct bpf_verifier_env *env)
22194
22190
22195
22191
static void free_states(struct bpf_verifier_env *env)
22196
22192
{
22197
- struct bpf_verifier_state_list *sl, *sln;
22193
+ struct bpf_verifier_state_list *sl;
22194
+ struct list_head *head, *pos, *tmp;
22198
22195
int i;
22199
22196
22200
- sl = env->free_list;
22201
- while (sl) {
22202
- sln = sl->next;
22197
+ list_for_each_safe(pos, tmp, &env->free_list) {
22198
+ sl = container_of(pos, struct bpf_verifier_state_list, node);
22203
22199
free_verifier_state(&sl->state, false);
22204
22200
kfree(sl);
22205
- sl = sln;
22206
22201
}
22207
- env->free_list = NULL ;
22202
+ INIT_LIST_HEAD(& env->free_list) ;
22208
22203
22209
22204
if (!env->explored_states)
22210
22205
return;
22211
22206
22212
22207
for (i = 0; i < state_htab_size(env); i++) {
22213
- sl = env->explored_states[i];
22208
+ head = & env->explored_states[i];
22214
22209
22215
- while (sl ) {
22216
- sln = sl->next ;
22210
+ list_for_each_safe(pos, tmp, head ) {
22211
+ sl = container_of(pos, struct bpf_verifier_state_list, node) ;
22217
22212
free_verifier_state(&sl->state, false);
22218
22213
kfree(sl);
22219
- sl = sln;
22220
22214
}
22221
- env->explored_states[i] = NULL ;
22215
+ INIT_LIST_HEAD(& env->explored_states[i]) ;
22222
22216
}
22223
22217
}
22224
22218
@@ -23186,12 +23180,16 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
23186
23180
env->test_reg_invariants = attr->prog_flags & BPF_F_TEST_REG_INVARIANTS;
23187
23181
23188
23182
env->explored_states = kvcalloc(state_htab_size(env),
23189
- sizeof(struct bpf_verifier_state_list * ),
23183
+ sizeof(struct list_head ),
23190
23184
GFP_USER);
23191
23185
ret = -ENOMEM;
23192
23186
if (!env->explored_states)
23193
23187
goto skip_full_check;
23194
23188
23189
+ for (i = 0; i < state_htab_size(env); i++)
23190
+ INIT_LIST_HEAD(&env->explored_states[i]);
23191
+ INIT_LIST_HEAD(&env->free_list);
23192
+
23195
23193
ret = check_btf_info_early(env, attr, uattr);
23196
23194
if (ret < 0)
23197
23195
goto skip_full_check;
0 commit comments