Re: Backporting callback handling fixes to stable 6.1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2024-06-20 at 13:18 +0800, Shung-Hsi Yu wrote:
> Hi Eduard,
> 
> I'm seeking suggestions for backporting callback handling fixes to the
> stable/linux-6.1.y (and similar branches), akin to what has been done
> for 6.6[1].

Hi Shung-Hsi,

I remember that porting to 6.6 was somewhat painful,
6.1 would be much worse, probably...

> Testing with the reproducer from Andrew Werner[2] it seems 6.1 has the
> same problem where the bpf_probe_read_user() call is only verified with
> the R1_w=fp-8 state, but not the R1_w=0xDEAD state because the latter
> was incorrectly pruned. So I believe the callback fixes are need.

Yes, the main problem with callbacks was that they were verified as if
called only once. This affects all functions accepting callbacks.

> The main difference from 6.6 is that 6.1 does not have BPF open-coded
> iterator, but AFAICT it does not mean "exact states comparison for
> iterator convergence checks" patch-set[3] can be dropped. This is
> because exact-state comparison from commit 2793a8b015f7 ("bpf: exact
> states comparison for iterator convergence checks") and loop-identifying
> algorithm in commit 2a0992829ea3 ("bpf: correct loop detection for
> iterators convergence") are critical for the fix; but it should be fine
> to ignore all changes to process_iter_*().

That is correct, that is the main mechanics of the fix.

> The "verify callbacks as if they are called unknown number of
> times" patch-set[4] name already suggest that it is needed, so no doubts
> there (again, dropping iterator-related changes).

Right.

I looked at the patches migrated for 6.6 vs current state of 6.1,
some thoughts below.

1.  3c4e420cb653 ("bpf: move explored_state() closer to the beginning of verifier.c ")
    - should apply as-is;
2.  4c97259abc9b ("bpf: extract same_callsites() as utility function ")
    - should apply as-is;
3.  2793a8b015f7 ("bpf: exact states comparison for iterator convergence checks ")
    - needs regs_exact() introduced/modified in:
      - 4a95c85c9948 ("bpf: perform byte-by-byte comparison only when necessary in regsafe()")
      - 4633a0068258 ("bpf: fix regs_exact() logic in regsafe() to remap IDs correctly")
      - 1ffc85d9298e ("bpf: Verify scalar ids mapping in regsafe() using check_ids()")
    - changes to process_iter_next_call() are not needed;
    - changes to regsafe() seem applicable;
    - changes to stacksafe() seem applicable;
    - changes to func_states_equal():
      - seem applicable, but there is a commit that removes
        memset for idmap_scratch from func_states_equal(),
        it is not necessary for this particular fix,
        but is a safety fix in itself:
        1ffc85d9298e ("bpf: Verify scalar ids mapping in regsafe() using check_ids()")
    - changes to is_state_visited():
      - ignore iterator related changes, just add a new parameter for
        states_equal() where necessary;
      - change to visited states eviction heuristic is probably needed
        (the hunk with "if (sl->miss_cnt > sl->hit_cnt * n + n)");
      - don't miss the hunk with "cur->dfs_depth = new->dfs_depth + 1;";
4.  389ede06c297 ("selftests/bpf: tests with delayed read/precision makrs in loop body ")
    [didn't look at this]
5.  2a0992829ea3 ("bpf: correct loop detection for iterators convergence ")
    - looks like it could be applied with minimal changes;
6.  64870feebecb ("selftests/bpf: test if state loops are detected in a tricky case ")
    [didn't look at this]
7.  b4d8239534fd ("bpf: print full verifier states on infinite loop detection ")
    [didn't look at this]

--- patch set boundary -------------------------------------------------------------------------

8.  977bc146d4eb ("selftests/bpf: track tcp payload offset as scalar in xdp_synproxy ")
    [didn't look at this]
9.  87eb0152bcc1 ("selftests/bpf: track string payload offset as scalar in strobemeta ")
    [didn't look at this]
10. 683b96f9606a ("bpf: extract __check_reg_arg() utility function ")
    A small refactoring, shouldn't be hard to port.
11. 58124a98cb8e ("bpf: extract setup_func_entry() utility function ")
    A small refactoring, shouldn't be hard to port.
12. ab5cfac139ab ("bpf: verify callbacks as if they are called unknown number of times ")
    - backtrack_insn() lacks Andrii's refactoring that introduces 'struct backtrack_state',
      technically it shouldn't be hard to repeat patch logic w/o that refactoring,
      but this would lead to further divergence with upstream;
    - backtrack_insn() lacks subseq_idx parameter;
    - __check_func_call() seems similar enough, so shouldn't be a big problem;
    - prepare_func_exit() similar enough;
    - check_helper_call() similar enough;
    - check_kfunc_call() it looks like kfunc KF_bpf_rbtree_add_impl
      (the only kfunc that calls a callback) is not in the kernel yet,
      so changes to check_kfunc_call are not necessary;
    - visit_insn() similar enough;
    - is_state_visited() needs a 'skip_inf_loop_check' label,
      but otherwise seems applicable;
13. 958465e217db ("selftests/bpf: tests for iterating callbacks ")
    - tools/testing/selftests/bpf/prog_tests/verifier.c is not in 6.1,
      so adding a custom progs/*.c driver program would be necessary;
14. cafe2c21508a ("bpf: widening for callback iterators ")
    - technically, this is not necessary from safety point of view,
      but exact states comparison is very restrictive,
      so porting this is probably a good idea;
    - shouldn't be hard to port if widen_imprecise_scalars() and co
      are already ported;
15. 9f3330aa644d ("selftests/bpf: test widening for iterating callbacks ")
    [didn't look at this]
16. bb124da69c47 ("bpf: keep track of max number of bpf_loop callback iterations ")
    - this is more "nice to have" patch, it fallbacks to enumeration
      of every iteration step for bpf_loop, if exact match/widening
      logic does not converge;
    - shouldn't be hard to port;
    - note also the following bug fix for this commit:
      https://lore.kernel.org/bpf/20240222154121.6991-1-eddyz87@xxxxxxxxx/
17. 57e2a52deeb1 ("selftests/bpf: check if max number of bpf_loop iterations is tracked ")
    [didn't look at this]

Also note the following patch from Alexei, relaxing exact states
comparison a bit:
https://lore.kernel.org/bpf/20240306031929.42666-3-alexei.starovoitov@xxxxxxxxx/

Hope this helps.
Sounds like a lot of work.
Feel free to ask any questions about the patch-sets.

Thanks,
Eduard





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux