@@ -341,10 +341,12 @@ static int realloc_verifier_state(struct bpf_verifier_state *state, int size,
341341 return 0 ;
342342}
343343
344- static void free_verifier_state (struct bpf_verifier_state * state )
344+ static void free_verifier_state (struct bpf_verifier_state * state ,
345+ bool free_self )
345346{
346347 kfree (state -> stack );
347- kfree (state );
348+ if (free_self )
349+ kfree (state );
348350}
349351
350352/* copy verifier state from src to dst growing dst stack space
@@ -382,6 +384,7 @@ static int pop_stack(struct bpf_verifier_env *env, int *prev_insn_idx,
382384 if (prev_insn_idx )
383385 * prev_insn_idx = head -> prev_insn_idx ;
384386 elem = head -> next ;
387+ free_verifier_state (& head -> st , false);
385388 kfree (head );
386389 env -> head = elem ;
387390 env -> stack_size -- ;
@@ -399,14 +402,14 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
399402 if (!elem )
400403 goto err ;
401404
402- err = copy_verifier_state (& elem -> st , cur );
403- if (err )
404- return NULL ;
405405 elem -> insn_idx = insn_idx ;
406406 elem -> prev_insn_idx = prev_insn_idx ;
407407 elem -> next = env -> head ;
408408 env -> head = elem ;
409409 env -> stack_size ++ ;
410+ err = copy_verifier_state (& elem -> st , cur );
411+ if (err )
412+ goto err ;
410413 if (env -> stack_size > BPF_COMPLEXITY_LIMIT_STACK ) {
411414 verbose (env , "BPF program is too complex\n" );
412415 goto err ;
@@ -3641,7 +3644,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
36413644 struct bpf_verifier_state_list * new_sl ;
36423645 struct bpf_verifier_state_list * sl ;
36433646 struct bpf_verifier_state * cur = env -> cur_state ;
3644- int i ;
3647+ int i , err ;
36453648
36463649 sl = env -> explored_states [insn_idx ];
36473650 if (!sl )
@@ -3679,7 +3682,12 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
36793682 return - ENOMEM ;
36803683
36813684 /* add new state to the head of linked list */
3682- copy_verifier_state (& new_sl -> state , cur );
3685+ err = copy_verifier_state (& new_sl -> state , cur );
3686+ if (err ) {
3687+ free_verifier_state (& new_sl -> state , false);
3688+ kfree (new_sl );
3689+ return err ;
3690+ }
36833691 new_sl -> next = env -> explored_states [insn_idx ];
36843692 env -> explored_states [insn_idx ] = new_sl ;
36853693 /* connect new state to parentage chain */
@@ -4424,6 +4432,7 @@ static void free_states(struct bpf_verifier_env *env)
44244432 if (sl )
44254433 while (sl != STATE_LIST_MARK ) {
44264434 sln = sl -> next ;
4435+ free_verifier_state (& sl -> state , false);
44274436 kfree (sl );
44284437 sl = sln ;
44294438 }
@@ -4494,7 +4503,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
44944503 env -> allow_ptr_leaks = capable (CAP_SYS_ADMIN );
44954504
44964505 ret = do_check (env );
4497- free_verifier_state (env -> cur_state );
4506+ free_verifier_state (env -> cur_state , true );
44984507 env -> cur_state = NULL ;
44994508
45004509skip_full_check :
@@ -4601,7 +4610,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops,
46014610 env -> allow_ptr_leaks = capable (CAP_SYS_ADMIN );
46024611
46034612 ret = do_check (env );
4604- free_verifier_state (env -> cur_state );
4613+ free_verifier_state (env -> cur_state , true );
46054614 env -> cur_state = NULL ;
46064615
46074616skip_full_check :
0 commit comments