Skip to content

Commit

Permalink
bpf: make state->dfs_depth < state->loop_entry->dfs_depth an invariant
Browse files Browse the repository at this point in the history
For a generic loop detection algorithm a graph node can be a loop
header for itself. However, state loop entries are computed for use in
is_state_visited(), where get_loop_entry(state)->branches is checked.
is_state_visited() also checks state->branches, thus the case when
state == state->loop_entry is not interesting for is_state_visited().

This change does not affect correctness, but simplifies
get_loop_entry() a bit and also simplifies change to
update_loop_entry() in patch 9.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250215110411.3236773-7-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Eduard Zingerman authored and Alexei Starovoitov committed Feb 19, 2025
1 parent c1ce663 commit bb7abf3
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,7 @@ static bool same_callsites(struct bpf_verifier_state *a, struct bpf_verifier_sta
* # Find outermost loop entry known for n
* def get_loop_entry(n):
* h = entries.get(n, None)
* while h in entries and entries[h] != h:
* while h in entries:
* h = entries[h]
* return h
*
Expand Down Expand Up @@ -1838,7 +1838,7 @@ static struct bpf_verifier_state *get_loop_entry(struct bpf_verifier_env *env,
struct bpf_verifier_state *topmost = st->loop_entry, *old;
u32 steps = 0;

while (topmost && topmost->loop_entry && topmost != topmost->loop_entry) {
while (topmost && topmost->loop_entry) {
if (steps++ > st->dfs_depth) {
WARN_ONCE(true, "verifier bug: infinite loop in get_loop_entry\n");
verbose(env, "verifier bug: infinite loop in get_loop_entry()\n");
Expand All @@ -1865,7 +1865,7 @@ static void update_loop_entry(struct bpf_verifier_state *cur, struct bpf_verifie
* hence 'cur' and 'hdr' are not in the same loop and there is
* no need to update cur->loop_entry.
*/
if (hdr->branches && hdr->dfs_depth <= (cur->loop_entry ?: cur)->dfs_depth) {
if (hdr->branches && hdr->dfs_depth < (cur->loop_entry ?: cur)->dfs_depth) {
cur->loop_entry = hdr;
hdr->used_as_loop_entry = true;
}
Expand Down

0 comments on commit bb7abf3

Please sign in to comment.