aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 3fb50757e812..315798037d6c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1772,16 +1772,21 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
1772 bitmap_from_u64(mask, stack_mask); 1772 bitmap_from_u64(mask, stack_mask);
1773 for_each_set_bit(i, mask, 64) { 1773 for_each_set_bit(i, mask, 64) {
1774 if (i >= func->allocated_stack / BPF_REG_SIZE) { 1774 if (i >= func->allocated_stack / BPF_REG_SIZE) {
1775 /* This can happen if backtracking 1775 /* the sequence of instructions:
1776 * is propagating stack precision where 1776 * 2: (bf) r3 = r10
1777 * caller has larger stack frame 1777 * 3: (7b) *(u64 *)(r3 -8) = r0
1778 * than callee, but backtrack_insn() should 1778 * 4: (79) r4 = *(u64 *)(r10 -8)
1779 * have returned -ENOTSUPP. 1779 * doesn't contain jmps. It's backtracked
1780 * as a single block.
1781 * During backtracking insn 3 is not recognized as
1782 * stack access, so at the end of backtracking
1783 * stack slot fp-8 is still marked in stack_mask.
1784 * However the parent state may not have accessed
1785 * fp-8 and it's "unallocated" stack space.
1786 * In such case fallback to conservative.
1780 */ 1787 */
1781 verbose(env, "BUG spi %d stack_size %d\n", 1788 mark_all_scalars_precise(env, st);
1782 i, func->allocated_stack); 1789 return 0;
1783 WARN_ONCE(1, "verifier backtracking bug");
1784 return -EFAULT;
1785 } 1790 }
1786 1791
1787 if (func->stack[i].slot_type[0] != STACK_SPILL) { 1792 if (func->stack[i].slot_type[0] != STACK_SPILL) {