| 1 | |
| 2 |
|
| 3 | #include <linux/bpf.h>
|
| 4 | #include <bpf/bpf_helpers.h>
|
| 5 | #include "bpf_misc.h"
|
| 6 |
|
| 7 |
|
| 8 | SEC("socket")
|
| 9 | __naked int read_uninit_stack_fixed_off(void *ctx)
|
| 10 | {
|
| 11 | asm volatile (" \
|
| 12 | r0 = 0; \
|
| 13 | /* force stack depth to be 128 */ \
|
| 14 | *(u64*)(r10 - 128) = r1; \
|
| 15 | r1 = *(u8 *)(r10 - 8 ); \
|
| 16 | r0 += r1; \
|
| 17 | r1 = *(u8 *)(r10 - 11); \
|
| 18 | r1 = *(u8 *)(r10 - 13); \
|
| 19 | r1 = *(u8 *)(r10 - 15); \
|
| 20 | r1 = *(u16*)(r10 - 16); \
|
| 21 | r1 = *(u32*)(r10 - 32); \
|
| 22 | r1 = *(u64*)(r10 - 64); \
|
| 23 | /* read from a spill of a wrong size, it is a separate \
|
| 24 | * branch in check_stack_read_fixed_off() \
|
| 25 | */ \
|
| 26 | *(u32*)(r10 - 72) = r1; \
|
| 27 | r1 = *(u64*)(r10 - 72); \
|
| 28 | r0 = 0; \
|
| 29 | exit; \
|
| 30 | "
|
| 31 | ::: __clobber_all);
|
| 32 | }
|
| 33 |
|
| 34 |
|
| 35 | SEC("socket")
|
| 36 | __naked int read_uninit_stack_var_off(void *ctx)
|
| 37 | {
|
| 38 | asm volatile (" \
|
| 39 | call %[bpf_get_prandom_u32]; \
|
| 40 | /* force stack depth to be 64 */ \
|
| 41 | *(u64*)(r10 - 64) = r0; \
|
| 42 | r0 = -r0; \
|
| 43 | /* give r0 a range [-31, -1] */ \
|
| 44 | if r0 s<= -32 goto exit_%=; \
|
| 45 | if r0 s>= 0 goto exit_%=; \
|
| 46 | /* access stack using r0 */ \
|
| 47 | r1 = r10; \
|
| 48 | r1 += r0; \
|
| 49 | r2 = *(u8*)(r1 + 0); \
|
| 50 | exit_%=: r0 = 0; \
|
| 51 | exit; \
|
| 52 | "
|
| 53 | :
|
| 54 | : __imm(bpf_get_prandom_u32)
|
| 55 | : __clobber_all);
|
| 56 | }
|
| 57 |
|
| 58 | static __noinline void dummy(void) {}
|
| 59 |
|
| 60 | |
| 61 | * Passed memory block should be marked as STACK_MISC after helper call.
|
| 62 |
|
| 63 | SEC("socket")
|
| 64 | __log_level(7) __msg("fp-104=mmmmmmmm")
|
| 65 | __naked int helper_uninit_to_misc(void *ctx)
|
| 66 | {
|
| 67 | asm volatile (" \
|
| 68 | /* force stack depth to be 128 */ \
|
| 69 | *(u64*)(r10 - 128) = r1; \
|
| 70 | r1 = r10; \
|
| 71 | r1 += -128; \
|
| 72 | r2 = 32; \
|
| 73 | r3 = 0; \
|
| 74 | call %[bpf_probe_read_user]; \
|
| 75 | /* Call to dummy() forces print_verifier_state(..., true), \
|
| 76 | * thus showing the stack state, matched by __msg(). \
|
| 77 | */ \
|
| 78 | call %[dummy]; \
|
| 79 | r1 = *(u64*)(r10 - 104); \
|
| 80 | r0 = 0; \
|
| 81 | exit; \
|
| 82 | "
|
| 83 | :
|
| 84 | : __imm(bpf_probe_read_user),
|
| 85 | __imm(dummy)
|
| 86 | : __clobber_all);
|
| 87 | }
|
| 88 |
|
| 89 | char _license[] SEC("license") = "GPL";
|