1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/tools/testing/selftests/bpf/verifier
Andrei Matei 6b4a64bafd bpf: Fix accesses to uninit stack slots
Privileged programs are supposed to be able to read uninitialized stack
memory (ever since 6715df8d5) but, before this patch, these accesses
were permitted inconsistently. In particular, accesses were permitted
above state->allocated_stack, but not below it. In other words, if the
stack was already "large enough", the access was permitted, but
otherwise the access was rejected instead of being allowed to "grow the
stack". This undesired rejection was happening in two places:
- in check_stack_slot_within_bounds()
- in check_stack_range_initialized()
This patch arranges for these accesses to be permitted. A bunch of tests
that were relying on the old rejection had to change; all of them were
changed to add also run unprivileged, in which case the old behavior
persists. One tests couldn't be updated - global_func16 - because it
can't run unprivileged for other reasons.

This patch also fixes the tracking of the stack size for variable-offset
reads. This second fix is bundled in the same commit as the first one
because they're inter-related. Before this patch, writes to the stack
using registers containing a variable offset (as opposed to registers
with fixed, known values) were not properly contributing to the
function's needed stack size. As a result, it was possible for a program
to verify, but then to attempt to read out-of-bounds data at runtime
because a too small stack had been allocated for it.

Each function tracks the size of the stack it needs in
bpf_subprog_info.stack_depth, which is maintained by
update_stack_depth(). For regular memory accesses, check_mem_access()
was calling update_state_depth() but it was passing in only the fixed
part of the offset register, ignoring the variable offset. This was
incorrect; the minimum possible value of that register should be used
instead.

This tracking is now fixed by centralizing the tracking of stack size in
grow_stack_state(), and by lifting the calls to grow_stack_state() to
check_stack_access_within_bounds() as suggested by Andrii. The code is
now simpler and more convincingly tracks the correct maximum stack size.
check_stack_range_initialized() can now rely on enough stack having been
allocated for the access; this helps with the fix for the first issue.

A few tests were changed to also check the stack depth computation. The
one that fails without this patch is verifier_var_off:stack_write_priv_vs_unpriv.

Fixes: 01f810ace9 ("bpf: Allow variable-offset stack access")
Reported-by: Hao Sun <sunhao.th@gmail.com>
Signed-off-by: Andrei Matei <andreimatei1@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20231208032519.260451-3-andreimatei1@gmail.com

Closes: https://lore.kernel.org/bpf/CABWLsev9g8UP_c3a=1qbuZUi20tGoUXoU07FPf-5FLvhOKOY+Q@mail.gmail.com/
2023-12-08 14:19:00 -08:00
..
.gitignore .gitignore: add SPDX License Identifier 2020-03-25 11:50:48 +01:00
atomic_and.c bpf, x86: Fix BPF_FETCH atomic and/or/xor with r0 as src 2021-02-22 18:03:11 +01:00
atomic_bounds.c bpf: Propagate stack bounds to registers in atomics w/ BPF_FETCH 2021-02-02 18:23:29 -08:00
atomic_cmpxchg.c bpf: Fix accesses to uninit stack slots 2023-12-08 14:19:00 -08:00
atomic_fetch.c bpf, selftests: Add test case for atomic fetch on spilled pointer 2021-12-14 19:33:06 -08:00
atomic_fetch_add.c bpf: Add tests for new BPF atomic operations 2021-01-14 18:34:29 -08:00
atomic_invalid.c bpf: Small BPF verifier log improvements 2022-03-03 16:54:10 +01:00
atomic_or.c bpf: Explicitly zero-extend R0 after 32-bit cmpxchg 2021-03-04 19:06:03 -08:00
atomic_xchg.c bpf: Add tests for new BPF atomic operations 2021-01-14 18:34:29 -08:00
atomic_xor.c selftests/bpf: Fix endianness issues in atomic tests 2021-02-10 11:55:22 -08:00
basic.c selftests/bpf: Fix test_verifier after introducing resolve_pseudo_ldimm64 2020-10-06 20:16:57 -07:00
basic_call.c selftests: bpf: break up test_verifier 2019-01-27 21:37:45 -08:00
basic_instr.c selftests/bpf: Fix a test_verifier failure 2023-07-27 18:54:16 -07:00
basic_stx_ldx.c selftests: bpf: break up test_verifier 2019-01-27 21:37:45 -08:00
bpf_loop_inline.c selftests/bpf: Fix test_verifier failed test in unprivileged mode 2022-07-21 21:03:25 -07:00
bpf_st_mem.c selftests/bpf: Add test for immediate spilled to stack 2023-11-01 22:30:27 -07:00
calls.c bpf: Fix accesses to uninit stack slots 2023-12-08 14:19:00 -08:00
ctx_sk_lookup.c selftests/bpf: Add tests for accessing ingress_ifindex in bpf_sk_lookup 2021-11-10 16:29:59 -08:00
ctx_skb.c selftests/bpf: Add F_NEEDS_EFFICIENT_UNALIGNED_ACCESS to some tests 2023-07-05 14:34:23 +02:00
dead_code.c selftests, bpf: Test that dead ldx_w insns are accepted 2021-08-13 17:46:26 +02:00
direct_value_access.c selftests/bpf: Mark tests that require unaligned memory access 2020-11-18 17:45:35 -08:00
event_output.c selftests/bpf: Fix cgroup sockopt verifier test 2020-07-11 01:32:15 +02:00
jit.c bpf: add selftests for lsh, rsh, arsh with reg operand 2022-10-19 16:53:51 -07:00
jmp32.c selftests/bpf: Add F_NEEDS_EFFICIENT_UNALIGNED_ACCESS to some tests 2023-07-05 14:34:23 +02:00
jset.c bpf, selftests: Adjust few selftest outcomes wrt unreachable code 2021-06-14 23:06:38 +02:00
jump.c bpf, selftests: Add verifier test case for imm=0,umin=0,umax=1 scalar 2022-07-01 12:56:27 -07:00
junk_insn.c selftests: bpf: break up test_verifier 2019-01-27 21:37:45 -08:00
ld_abs.c selftests: bpf: break up the rest of test_verifier 2019-01-27 21:37:45 -08:00
ld_dw.c selftests/bpf: synthetic tests to push verifier limits 2019-04-04 01:27:38 +02:00
ld_imm64.c bpf: handle ldimm64 properly in check_cfg() 2023-11-09 20:11:20 -08:00
map_kptr.c selftests/bpf: Add F_NEEDS_EFFICIENT_UNALIGNED_ACCESS to some tests 2023-07-05 14:34:23 +02:00
perf_event_sample_period.c selftests/bpf: Use __BYTE_ORDER__ 2021-10-25 20:39:42 -07:00
precise.c bpf: support non-r10 register spill/fill to/from stack in precision tracking 2023-12-05 13:40:20 -08:00
scale.c selftests/bpf: two scale tests 2019-04-16 10:18:15 +02:00
sleepable.c bpf: Allow BPF_PROG_TYPE_STRUCT_OPS programs to be sleepable 2023-01-25 10:25:57 -08:00
wide_access.c selftests/bpf: Mark tests that require unaligned memory access 2020-11-18 17:45:35 -08:00