Skip to content

Commit a361c00

Browse files
committed
bpf: Remove redundant free_verifier_state()/pop_stack()
Eduard points out [1]: Same cleanup cycles are done in push_stack() and push_async_cb(), both functions are only reachable from do_check_common() via do_check() -> do_check_insn(). Hence, I think that cur state should not be freed in push_*() functions and pop_stack() loop there is not needed. This would also fix the 'symptom' for [2], but the issue has a more logical (and also simpler) fix which was sent separately. Caller must return an error for which error_recoverable_with_nospec(err) is false, otherwise we try to recover and access the stale state. [1] https://lore.kernel.org/all/[email protected]/ [2] https://lore.kernel.org/all/[email protected]/ Reported-by: Eduard Zingerman <[email protected]> Signed-off-by: Luis Gerhorst <[email protected]>
1 parent 28f0238 commit a361c00

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

kernel/bpf/verifier.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,10 +2066,10 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
20662066
}
20672067
return &elem->st;
20682068
err:
2069-
free_verifier_state(env->cur_state, true);
2070-
env->cur_state = NULL;
2071-
/* pop all elements and return */
2072-
while (!pop_stack(env, NULL, NULL, false));
2069+
/* free_verifier_state() and pop_stack() loop will be done in
2070+
* do_check_common(). Caller must return an error for which
2071+
* error_recoverable_with_nospec(err) is false.
2072+
*/
20732073
return NULL;
20742074
}
20752075

@@ -2838,10 +2838,10 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
28382838
elem->st.frame[0] = frame;
28392839
return &elem->st;
28402840
err:
2841-
free_verifier_state(env->cur_state, true);
2842-
env->cur_state = NULL;
2843-
/* pop all elements and return */
2844-
while (!pop_stack(env, NULL, NULL, false));
2841+
/* free_verifier_state() and pop_stack() loop will be done in
2842+
* do_check_common(). Caller must return an error for which
2843+
* error_recoverable_with_nospec(err) is false.
2844+
*/
28452845
return NULL;
28462846
}
28472847

@@ -22904,13 +22904,9 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
2290422904

2290522905
ret = do_check(env);
2290622906
out:
22907-
/* check for NULL is necessary, since cur_state can be freed inside
22908-
* do_check() under memory pressure.
22909-
*/
22910-
if (env->cur_state) {
22911-
free_verifier_state(env->cur_state, true);
22912-
env->cur_state = NULL;
22913-
}
22907+
WARN_ON_ONCE(!env->cur_state);
22908+
free_verifier_state(env->cur_state, true);
22909+
env->cur_state = NULL;
2291422910
while (!pop_stack(env, NULL, NULL, false));
2291522911
if (!ret && pop_log)
2291622912
bpf_vlog_reset(&env->log, 0);

0 commit comments

Comments
 (0)