bpf: add support for KASAN checks in JITed programs - #13402
bpf: add support for KASAN checks in JITed programs#13402kernel-patches-daemon-bpf[bot] wants to merge 9 commits into
Conversation
|
Upstream branch: 669e4fa |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
|
Forwarding comment 5376351231 via email |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
|
Forwarding comment 5376399561 via email |
|
Forwarding comment 5376418409 via email |
AI reviewed your patch. Please fix the bug or email reply why it's not a bug. In-Reply-To-Subject: |
|
Forwarding comment 5376443713 via email |
7b6ba88 to
d696d45
Compare
|
Upstream branch: a284ed4 |
7af63ba to
e2a3040
Compare
d696d45 to
b8b6131
Compare
|
Upstream branch: 5e289c5 |
e2a3040 to
f997965
Compare
b8b6131 to
71e031f
Compare
In order to prepare to emit KASAN checks in JITed programs, JIT compilers need to be aware about whether some load/store instructions are targeting the bpf program stack, as those should not be monitored (we already have guard pages for that, and it is difficult anyway to correctly monitor any kind of data passed on stack). To support this need, make the BPF verifier mark the instructions depending on whether they could access or not memory other than stack. As different states in the verifier could lead to different memory types for the same access, just marking an instruction as accessing stack only is not enough (it could be some other memory type in another verifier state), so the algorithm rather sets by default any load/store instruction as stack only, and if _any_ state leads to any memory access type other than PTR_TO_STACK, it overrides this setting. It also takes care about shifting back the instruction marking in adjust_insn_aux_data if the verifier patches instructions. However, if the verifier generates new BPF_ST/BPF_STX/BPF_LDX while patching some instructions, those new ones are systematically marked as non-stack-accessing: this may over-instrument a few memory accessing instructions, but it allows making sure that we will not miss accidentally any. Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Add a new Kconfig option CONFIG_BPF_JIT_KASAN that automatically enables generic KASAN (Kernel Address SANitizer) memory access checks for JIT-compiled BPF programs as well, when both KASAN (and more specifically, generic KASAN with KASAN_VMALLOC) and JIT compiler are enabled. This new Kconfig is not a user selectable one: it is automatically enabled if KASAN is enabled on a compatible platform. When enabled, the JIT compiler will emit shadow memory checks before memory loads and stores to detect use-after-free or out-of-bounds accesses at runtime. The option is gated behind HAVE_EBPF_JIT_KASAN, as it needs proper arch-specific implementation. Acked-by: Andrey Konovalov <andreyknvl@gmail.com> Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
In order to prepare for KASAN checks insertion before every memory-related load or store, group all BPF_ST instructions that indeed access memory in a single helper to allow instrumenting those in one call, rather than having to instrument all cases individually. Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Insert KASAN shadow memory checks before memory load and store
operations in JIT-compiled BPF programs. This helps detect memory safety
bugs such as use-after-free and out-of-bounds accesses at runtime.
The main instructions being targeted are BPF_ST, BPF_STX and BPF_LDX,
but not all of them are being instrumented:
- if the load/store instruction is in fact accessing the program stack,
emit_kasan_check silently skips the instrumentation, as we can already
benefit from guard pages to monitor stack accesses.
- if the load/store instruction is a BPF_PROBE_MEM or a BPF_PROBE_ATOMIC
instruction, we do not instrument it, as the passed address can fault
(hence the custom fault management with BPF_PROBE_XXX instructions),
and so the corresponding kasan check could fault as well.
To support those new instructions insertion, create the
emit_kasan_check() helper that emits KASAN shadow memory checks before
memory accesses in JIT-compiled BPF programs. The implementation relies
on the existing __asan_{load,store}X functions from KASAN subsystem. The
helper:
- saves registers. This includes caller-saved registers, but also
temporary registers, as those were possibly used by the
affected program. Theoretically, r10 and r11 should be saved as well,
but the number of called function and their scope being limited, they
are skipped for the sake of reducing the overhead
- computes the accessed address and stores it in %rdi
- calls the relevant function, depending on the instruction being a load
or a store, and the size of the access.
- restores registers
The special care needed when inserting this instrumentation comes at the
cost of a non negligeable increase in JITed code size. For example, a
bare
mov 0x0(%si),rbx # Load in rbx content at address stored in rsi
becomes
push %rax
push %rcx
push %rdx
push %rsi
push %rdi
push %r8
push %r9
mov %rsi,%rdi
call 0xffffffff81da0a60 <__asan_load8>
pop %r9
pop %r8
pop %rdi
pop %rsi
pop %rdx
pop %rcx
pop %rax
mov 0x0(%rsi),rbx
Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Mark x86 as supporting KASAN checks in JITed programs so that the corresponding JIT compiler inserts checks on the translated instructions. Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
cmdline_contains is used by BPF selftests to check the presence of specific kernel commandline parameters, but it currently suffers from two issues: - the read commandline isn't NULL terminated right after the read data but only at the end of the buffer, leaving uninitialized bytes that are then possibly tokenized - the comparison of found tokens is done based on the size of found token. This could lead to too-short-but-matching tokens to wrongly match the search pattern. Enforce stricter checks in cmdline_contains to avoid accidental matches. Fixes: 399f618 ("selftests/bpf: Fix selftests broken by mitigations=off") Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Add two simple helpers to allow checking whether KASAN for eBPF tests should be executed: - one helper to check if BPF_JIT_KASAN is enabled in kernel configuration - one helper to check if the kernel is running with kasan_multi_shot (otherwise only the first test will be able to trigger a report) Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Move set_bpf_jit_harden to testing helpers so that other selftests can change the hardening configuration without re-implementing a helper. Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Add a basic KASAN test runner that loads and test-run programs that can trigger memory management bugs. The test captures kernel logs and ensure that the expected KASAN splat is emitted by searching for the corresponding first lines in the report, hence validated that the needed instrumentation has been inserted by the JIT compiler before the relevant memory accesses. To allow each test to trigger the expected report, the kernel must run with the kasan_multi_shot configuration. The runner covers different cases and settings: in the nominal case, it validates kasan reports on basic instructions (on all supported accesses sizes) but also when report _should not_ be emitted (eg: for accesses on program stack). The runner also comes with a few specialized tests that are then not executed for all sizes/locations: - specific atomic ops - test for instructions involving different verifier states, with some states flagging memory as stack, and other states as non-stack memory - tests that validate the stack marking shifting when a patch is emitted by the verifier (zext/rnd_hi32, constant blindind). Most of those tests are able to trigger kasan reports by altering the shadow memory (triggering faulty accesses is otherwise complex, because of the verifier). A few tests trigger actual faulty accesses (eg out-of-bound accesses) A few of those tests depends on cpuv4 (load_acquire and store_release). # ./test_progs -a kasan #171/1 kasan/st_1_not_on_stack:OK #171/2 kasan/st_1_on_stack:OK #171/3 kasan/st_2_not_on_stack:OK #171/4 kasan/st_2_on_stack:OK #171/5 kasan/st_4_not_on_stack:OK #171/6 kasan/st_4_on_stack:OK #171/7 kasan/st_8_not_on_stack:OK #171/8 kasan/st_8_on_stack:OK #171/9 kasan/stx_1_not_on_stack:OK #171/10 kasan/stx_1_on_stack:OK #171/11 kasan/stx_2_not_on_stack:OK #171/12 kasan/stx_2_on_stack:OK #171/13 kasan/stx_4_not_on_stack:OK #171/14 kasan/stx_4_on_stack:OK #171/15 kasan/stx_8_not_on_stack:OK #171/16 kasan/stx_8_on_stack:OK #171/17 kasan/ldx_1_not_on_stack:OK #171/18 kasan/ldx_1_on_stack:OK #171/19 kasan/ldx_2_not_on_stack:OK #171/20 kasan/ldx_2_on_stack:OK #171/21 kasan/ldx_4_not_on_stack:OK #171/22 kasan/ldx_4_on_stack:OK #171/23 kasan/ldx_8_not_on_stack:OK #171/24 kasan/ldx_8_on_stack:OK #171/25 kasan/simple_atomic_4_not_on_stack:OK #171/26 kasan/simple_atomic_4_on_stack:OK #171/27 kasan/simple_atomic_8_not_on_stack:OK #171/28 kasan/simple_atomic_8_on_stack:OK #171/29 kasan/simple_atomic_fetch:OK #171/30 kasan/simple_atomic_fetch:OK #171/31 kasan/load_acquire_1_not_on_stack:SKIP #171/32 kasan/load_acquire_1_on_stack:SKIP #171/33 kasan/load_acquire_2_not_on_stack:SKIP #171/34 kasan/load_acquire_2_on_stack:SKIP #171/35 kasan/load_acquire_4_not_on_stack:SKIP #171/36 kasan/load_acquire_4_on_stack:SKIP #171/37 kasan/load_acquire_8_not_on_stack:SKIP #171/38 kasan/load_acquire_8_on_stack:SKIP #171/39 kasan/store_release_1_not_on_stack:SKIP #171/40 kasan/store_release_1_on_stack:SKIP #171/41 kasan/store_release_2_not_on_stack:SKIP #171/42 kasan/store_release_2_on_stack:SKIP #171/43 kasan/store_release_4_not_on_stack:SKIP #171/44 kasan/store_release_4_on_stack:SKIP #171/45 kasan/store_release_8_not_on_stack:SKIP #171/46 kasan/store_release_8_on_stack:SKIP #171/47 kasan/ldx_patched:OK #171/48 kasan/ldx_patched:OK #171/49 kasan/verifier_paths_stack_and_non_stack:OK #171/50 kasan/ldx_oob_1_not_on_stack:OK #171/51 kasan/ldx_oob_2_not_on_stack:OK #171/52 kasan/ldx_oob_4_not_on_stack:OK #171/53 kasan/ldx_oob_8_not_on_stack:OK #171/54 kasan/st_blinded:OK #171 kasan:OK (SKIP: 16/54) Summary: 1/38 PASSED, 16 SKIPPED, 0 FAILED Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
|
Upstream branch: 5e289c5 |
f997965 to
ac71811
Compare
Pull request for series with
subject: bpf: add support for KASAN checks in JITed programs
version: 7
url: https://patchwork.kernel.org/project/netdevbpf/list/?series=1150032