|
| 1 | +bpf: Fix a kernel verifier crash in stacksafe() |
| 2 | + |
| 3 | +jira LE-2177 |
| 4 | +cve CVE-2024-45020 |
| 5 | +Rebuild_History Non-Buildable kernel-5.14.0-503.19.1.el9_5 |
| 6 | +commit-author Yonghong Song < [email protected]> |
| 7 | +commit bed2eb964c70b780fb55925892a74f26cb590b25 |
| 8 | +Empty-Commit: Cherry-Pick Conflicts during history rebuild. |
| 9 | +Will be included in final tarball splat. Ref for failed cherry-pick at: |
| 10 | +ciq/ciq_backports/kernel-5.14.0-503.19.1.el9_5/bed2eb96.failed |
| 11 | + |
| 12 | +Daniel Hodges reported a kernel verifier crash when playing with sched-ext. |
| 13 | +Further investigation shows that the crash is due to invalid memory access |
| 14 | +in stacksafe(). More specifically, it is the following code: |
| 15 | + |
| 16 | + if (exact != NOT_EXACT && |
| 17 | + old->stack[spi].slot_type[i % BPF_REG_SIZE] != |
| 18 | + cur->stack[spi].slot_type[i % BPF_REG_SIZE]) |
| 19 | + return false; |
| 20 | + |
| 21 | +The 'i' iterates old->allocated_stack. |
| 22 | +If cur->allocated_stack < old->allocated_stack the out-of-bound |
| 23 | +access will happen. |
| 24 | + |
| 25 | +To fix the issue add 'i >= cur->allocated_stack' check such that if |
| 26 | +the condition is true, stacksafe() should fail. Otherwise, |
| 27 | +cur->stack[spi].slot_type[i % BPF_REG_SIZE] memory access is legal. |
| 28 | + |
| 29 | +Fixes: 2793a8b015f7 ("bpf: exact states comparison for iterator convergence checks") |
| 30 | + Cc: Eduard Zingerman < [email protected]> |
| 31 | + Reported-by: Daniel Hodges < [email protected]> |
| 32 | + Acked-by: Eduard Zingerman < [email protected]> |
| 33 | + Signed-off-by: Yonghong Song < [email protected]> |
| 34 | +Link: https://lore.kernel.org/r/ [email protected] |
| 35 | + Signed-off-by: Alexei Starovoitov < [email protected]> |
| 36 | +(cherry picked from commit bed2eb964c70b780fb55925892a74f26cb590b25) |
| 37 | + Signed-off-by: Jonathan Maple < [email protected]> |
| 38 | + |
| 39 | +# Conflicts: |
| 40 | +# kernel/bpf/verifier.c |
| 41 | +diff --cc kernel/bpf/verifier.c |
| 42 | +index 2ca877463352,d8520095ca03..000000000000 |
| 43 | +--- a/kernel/bpf/verifier.c |
| 44 | ++++ b/kernel/bpf/verifier.c |
| 45 | +@@@ -16463,12 -16883,14 +16463,19 @@@ static bool stacksafe(struct bpf_verifi |
| 46 | + |
| 47 | + spi = i / BPF_REG_SIZE; |
| 48 | + |
| 49 | +++<<<<<<< HEAD |
| 50 | + + if (exact && |
| 51 | + + old->stack[spi].slot_type[i % BPF_REG_SIZE] != |
| 52 | + + cur->stack[spi].slot_type[i % BPF_REG_SIZE]) |
| 53 | +++======= |
| 54 | ++ if (exact != NOT_EXACT && |
| 55 | ++ (i >= cur->allocated_stack || |
| 56 | ++ old->stack[spi].slot_type[i % BPF_REG_SIZE] != |
| 57 | ++ cur->stack[spi].slot_type[i % BPF_REG_SIZE])) |
| 58 | +++>>>>>>> bed2eb964c70 (bpf: Fix a kernel verifier crash in stacksafe()) |
| 59 | + return false; |
| 60 | + |
| 61 | + - if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ) |
| 62 | + - && exact == NOT_EXACT) { |
| 63 | + + if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ) && !exact) { |
| 64 | + i += BPF_REG_SIZE - 1; |
| 65 | + /* explored state didn't use this */ |
| 66 | + continue; |
| 67 | +* Unmerged path kernel/bpf/verifier.c |
0 commit comments