diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2023-03-13 13:20:58 -0700 | 
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2023-03-13 13:21:22 -0700 | 
| commit | a33a6eaa19d3af261e8708bfc8ba62020703117f (patch) | |
| tree | 9cabe0038dc0fe546b994a4c915612f204004067 /tools/testing/selftests/bpf | |
| parent | e8c8361cfdbf450f760e8a2bdbd4222d1947366b (diff) | |
| parent | bf9bec4cb3a401a14c24a7ef937d3c26aff9ad60 (diff) | |
Merge branch 'bpf: Allow reads from uninit stack'
Merge commit bf9bec4cb3a4 ("Merge branch 'bpf: Allow reads from uninit stack'")
from bpf-next to bpf tree to address verification issues in some programs
due to stack usage.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/testing/selftests/bpf')
| -rw-r--r-- | tools/testing/selftests/bpf/prog_tests/uninit_stack.c | 9 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/progs/test_global_func10.c | 8 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/progs/uninit_stack.c | 87 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/calls.c | 13 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/helper_access_var_len.c | 104 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/int_ptr.c | 9 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/search_pruning.c | 13 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/sock.c | 27 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/spill_fill.c | 7 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/verifier/var_off.c | 52 | 
10 files changed, 194 insertions, 135 deletions
| diff --git a/tools/testing/selftests/bpf/prog_tests/uninit_stack.c b/tools/testing/selftests/bpf/prog_tests/uninit_stack.c new file mode 100644 index 000000000000..e64c71948491 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/uninit_stack.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <test_progs.h> +#include "uninit_stack.skel.h" + +void test_uninit_stack(void) +{ +	RUN_TESTS(uninit_stack); +} diff --git a/tools/testing/selftests/bpf/progs/test_global_func10.c b/tools/testing/selftests/bpf/progs/test_global_func10.c index 98327bdbbfd2..8fba3f3649e2 100644 --- a/tools/testing/selftests/bpf/progs/test_global_func10.c +++ b/tools/testing/selftests/bpf/progs/test_global_func10.c @@ -5,12 +5,12 @@  #include "bpf_misc.h"  struct Small { -	int x; +	long x;  };  struct Big { -	int x; -	int y; +	long x; +	long y;  };  __noinline int foo(const struct Big *big) @@ -22,7 +22,7 @@ __noinline int foo(const struct Big *big)  }  SEC("cgroup_skb/ingress") -__failure __msg("invalid indirect read from stack") +__failure __msg("invalid indirect access to stack")  int global_func10(struct __sk_buff *skb)  {  	const struct Small small = {.x = skb->len }; diff --git a/tools/testing/selftests/bpf/progs/uninit_stack.c b/tools/testing/selftests/bpf/progs/uninit_stack.c new file mode 100644 index 000000000000..8a403470e557 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/uninit_stack.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/bpf.h> +#include <bpf/bpf_helpers.h> +#include "bpf_misc.h" + +/* Read an uninitialized value from stack at a fixed offset */ +SEC("socket") +__naked int read_uninit_stack_fixed_off(void *ctx) +{ +	asm volatile ("					\ +		r0 = 0;					\ +		/* force stack depth to be 128 */	\ +		*(u64*)(r10 - 128) = r1;		\ +		r1 = *(u8 *)(r10 - 8 );			\ +		r0 += r1;				\ +		r1 = *(u8 *)(r10 - 11);			\ +		r1 = *(u8 *)(r10 - 13);			\ +		r1 = *(u8 *)(r10 - 15);			\ +		r1 = *(u16*)(r10 - 16);			\ +		r1 = *(u32*)(r10 - 32);			\ +		r1 = *(u64*)(r10 - 64);			\ +		/* read from a spill of a wrong size, it is a separate	\ +		 * branch in check_stack_read_fixed_off()		\ +		 */					\ +		*(u32*)(r10 - 72) = r1;			\ +		r1 = *(u64*)(r10 - 72);			\ +		r0 = 0;					\ +		exit;					\ +" +		      ::: __clobber_all); +} + +/* Read an uninitialized value from stack at a variable offset */ +SEC("socket") +__naked int read_uninit_stack_var_off(void *ctx) +{ +	asm volatile ("					\ +		call %[bpf_get_prandom_u32];		\ +		/* force stack depth to be 64 */	\ +		*(u64*)(r10 - 64) = r0;			\ +		r0 = -r0;				\ +		/* give r0 a range [-31, -1] */		\ +		if r0 s<= -32 goto exit_%=;		\ +		if r0 s>= 0 goto exit_%=;		\ +		/* access stack using r0 */		\ +		r1 = r10;				\ +		r1 += r0;				\ +		r2 = *(u8*)(r1 + 0);			\ +exit_%=:	r0 = 0;					\ +		exit;					\ +" +		      : +		      : __imm(bpf_get_prandom_u32) +		      : __clobber_all); +} + +static __noinline void dummy(void) {} + +/* Pass a pointer to uninitialized stack memory to a helper. + * Passed memory block should be marked as STACK_MISC after helper call. + */ +SEC("socket") +__log_level(7) __msg("fp-104=mmmmmmmm") +__naked int helper_uninit_to_misc(void *ctx) +{ +	asm volatile ("					\ +		/* force stack depth to be 128 */	\ +		*(u64*)(r10 - 128) = r1;		\ +		r1 = r10;				\ +		r1 += -128;				\ +		r2 = 32;				\ +		call %[bpf_trace_printk];		\ +		/* Call to dummy() forces print_verifier_state(..., true),	\ +		 * thus showing the stack state, matched by __msg().		\ +		 */					\ +		call %[dummy];				\ +		r0 = 0;					\ +		exit;					\ +" +		      : +		      : __imm(bpf_trace_printk), +			__imm(dummy) +		      : __clobber_all); +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/verifier/calls.c b/tools/testing/selftests/bpf/verifier/calls.c index 9d993926bf0e..289ed202ec66 100644 --- a/tools/testing/selftests/bpf/verifier/calls.c +++ b/tools/testing/selftests/bpf/verifier/calls.c @@ -2221,19 +2221,22 @@  	 * that fp-8 stack slot was unused in the fall-through  	 * branch and will accept the program incorrectly  	 */ -	BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 2, 2), +	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), +	BPF_JMP_IMM(BPF_JGT, BPF_REG_0, 2, 2),  	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),  	BPF_JMP_IMM(BPF_JA, 0, 0, 0),  	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),  	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),  	BPF_LD_MAP_FD(BPF_REG_1, 0),  	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), +	BPF_MOV64_IMM(BPF_REG_0, 0),  	BPF_EXIT_INSN(),  	}, -	.fixup_map_hash_48b = { 6 }, -	.errstr = "invalid indirect read from stack R2 off -8+0 size 8", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_XDP, +	.fixup_map_hash_48b = { 7 }, +	.errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"calls: ctx read at start of subprog", diff --git a/tools/testing/selftests/bpf/verifier/helper_access_var_len.c b/tools/testing/selftests/bpf/verifier/helper_access_var_len.c index a6c869a7319c..9c4885885aba 100644 --- a/tools/testing/selftests/bpf/verifier/helper_access_var_len.c +++ b/tools/testing/selftests/bpf/verifier/helper_access_var_len.c @@ -29,19 +29,30 @@  {  	"helper access to variable memory: stack, bitwise AND, zero included",  	.insns = { -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), -	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), -	BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128), -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128), -	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64), -	BPF_MOV64_IMM(BPF_REG_3, 0), -	BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), +	/* set max stack size */ +	BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), +	/* set r3 to a random value */ +	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), +	BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), +	/* use bitwise AND to limit r3 range to [0, 64] */ +	BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 64), +	BPF_LD_MAP_FD(BPF_REG_1, 0), +	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), +	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), +	BPF_MOV64_IMM(BPF_REG_4, 0), +	/* Call bpf_ringbuf_output(), it is one of a few helper functions with +	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. +	 * For unpriv this should signal an error, because memory at &fp[-64] is +	 * not initialized. +	 */ +	BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),  	BPF_EXIT_INSN(),  	}, -	.errstr = "invalid indirect read from stack R1 off -64+0 size 64", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_TRACEPOINT, +	.fixup_map_ringbuf = { 4 }, +	.errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"helper access to variable memory: stack, bitwise AND + JMP, wrong max", @@ -183,20 +194,31 @@  {  	"helper access to variable memory: stack, JMP, no min check",  	.insns = { -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), -	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), -	BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128), -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128), -	BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3), -	BPF_MOV64_IMM(BPF_REG_3, 0), -	BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), +	/* set max stack size */ +	BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), +	/* set r3 to a random value */ +	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), +	BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), +	/* use JMP to limit r3 range to [0, 64] */ +	BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 64, 6), +	BPF_LD_MAP_FD(BPF_REG_1, 0), +	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), +	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), +	BPF_MOV64_IMM(BPF_REG_4, 0), +	/* Call bpf_ringbuf_output(), it is one of a few helper functions with +	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. +	 * For unpriv this should signal an error, because memory at &fp[-64] is +	 * not initialized. +	 */ +	BPF_EMIT_CALL(BPF_FUNC_ringbuf_output),  	BPF_MOV64_IMM(BPF_REG_0, 0),  	BPF_EXIT_INSN(),  	}, -	.errstr = "invalid indirect read from stack R1 off -64+0 size 64", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_TRACEPOINT, +	.fixup_map_ringbuf = { 4 }, +	.errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"helper access to variable memory: stack, JMP (signed), no min check", @@ -564,29 +586,41 @@  {  	"helper access to variable memory: 8 bytes leak",  	.insns = { -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), -	BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), +	/* set max stack size */ +	BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), +	/* set r3 to a random value */ +	BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), +	BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), +	BPF_LD_MAP_FD(BPF_REG_1, 0), +	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), +	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64),  	BPF_MOV64_IMM(BPF_REG_0, 0),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40), +	/* Note: fp[-32] left uninitialized */  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),  	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), -	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128), -	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128), -	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63), -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), -	BPF_MOV64_IMM(BPF_REG_3, 0), -	BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), -	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), +	/* Limit r3 range to [1, 64] */ +	BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 63), +	BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 1), +	BPF_MOV64_IMM(BPF_REG_4, 0), +	/* Call bpf_ringbuf_output(), it is one of a few helper functions with +	 * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. +	 * For unpriv this should signal an error, because memory region [1, 64] +	 * at &fp[-64] is not fully initialized. +	 */ +	BPF_EMIT_CALL(BPF_FUNC_ringbuf_output), +	BPF_MOV64_IMM(BPF_REG_0, 0),  	BPF_EXIT_INSN(),  	}, -	.errstr = "invalid indirect read from stack R1 off -64+32 size 64", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_TRACEPOINT, +	.fixup_map_ringbuf = { 3 }, +	.errstr_unpriv = "invalid indirect read from stack R2 off -64+32 size 64", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"helper access to variable memory: 8 bytes no leak (init memory)", diff --git a/tools/testing/selftests/bpf/verifier/int_ptr.c b/tools/testing/selftests/bpf/verifier/int_ptr.c index 070893fb2900..02d9e004260b 100644 --- a/tools/testing/selftests/bpf/verifier/int_ptr.c +++ b/tools/testing/selftests/bpf/verifier/int_ptr.c @@ -54,12 +54,13 @@  		/* bpf_strtoul() */  		BPF_EMIT_CALL(BPF_FUNC_strtoul), -		BPF_MOV64_IMM(BPF_REG_0, 1), +		BPF_MOV64_IMM(BPF_REG_0, 0),  		BPF_EXIT_INSN(),  	}, -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, -	.errstr = "invalid indirect read from stack R4 off -16+4 size 8", +	.result_unpriv = REJECT, +	.errstr_unpriv = "invalid indirect read from stack R4 off -16+4 size 8", +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"ARG_PTR_TO_LONG misaligned", diff --git a/tools/testing/selftests/bpf/verifier/search_pruning.c b/tools/testing/selftests/bpf/verifier/search_pruning.c index d63fd8991b03..745d6b5842fd 100644 --- a/tools/testing/selftests/bpf/verifier/search_pruning.c +++ b/tools/testing/selftests/bpf/verifier/search_pruning.c @@ -128,9 +128,10 @@  		BPF_EXIT_INSN(),  	},  	.fixup_map_hash_8b = { 3 }, -	.errstr = "invalid read from stack off -16+0 size 8", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_TRACEPOINT, +	.errstr_unpriv = "invalid read from stack off -16+0 size 8", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"precision tracking for u32 spill/fill", @@ -258,6 +259,8 @@  	BPF_EXIT_INSN(),  	},  	.flags = BPF_F_TEST_STATE_FREQ, -	.errstr = "invalid read from stack off -8+1 size 8", -	.result = REJECT, +	.errstr_unpriv = "invalid read from stack off -8+1 size 8", +	.result_unpriv = REJECT, +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  }, diff --git a/tools/testing/selftests/bpf/verifier/sock.c b/tools/testing/selftests/bpf/verifier/sock.c index d11d0b28be41..108dd3ee1edd 100644 --- a/tools/testing/selftests/bpf/verifier/sock.c +++ b/tools/testing/selftests/bpf/verifier/sock.c @@ -531,33 +531,6 @@  	.result = ACCEPT,  },  { -	"sk_storage_get(map, skb->sk, &stack_value, 1): partially init stack_value", -	.insns = { -	BPF_MOV64_IMM(BPF_REG_2, 0), -	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8), -	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offsetof(struct __sk_buff, sk)), -	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 2), -	BPF_MOV64_IMM(BPF_REG_0, 0), -	BPF_EXIT_INSN(), -	BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), -	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), -	BPF_MOV64_IMM(BPF_REG_0, 0), -	BPF_EXIT_INSN(), -	BPF_MOV64_IMM(BPF_REG_4, 1), -	BPF_MOV64_REG(BPF_REG_3, BPF_REG_10), -	BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -8), -	BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), -	BPF_LD_MAP_FD(BPF_REG_1, 0), -	BPF_EMIT_CALL(BPF_FUNC_sk_storage_get), -	BPF_MOV64_IMM(BPF_REG_0, 0), -	BPF_EXIT_INSN(), -	}, -	.fixup_sk_storage_map = { 14 }, -	.prog_type = BPF_PROG_TYPE_SCHED_CLS, -	.result = REJECT, -	.errstr = "invalid indirect read from stack", -}, -{  	"bpf_map_lookup_elem(smap, &key)",  	.insns = {  	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0), diff --git a/tools/testing/selftests/bpf/verifier/spill_fill.c b/tools/testing/selftests/bpf/verifier/spill_fill.c index 9bb302dade23..d1463bf4949a 100644 --- a/tools/testing/selftests/bpf/verifier/spill_fill.c +++ b/tools/testing/selftests/bpf/verifier/spill_fill.c @@ -171,9 +171,10 @@  	BPF_MOV64_IMM(BPF_REG_0, 0),  	BPF_EXIT_INSN(),  	}, -	.result = REJECT, -	.errstr = "invalid read from stack off -4+0 size 4", -	.prog_type = BPF_PROG_TYPE_SCHED_CLS, +	.result_unpriv = REJECT, +	.errstr_unpriv = "invalid read from stack off -4+0 size 4", +	/* in privileged mode reads from uninitialized stack locations are permitted */ +	.result = ACCEPT,  },  {  	"Spill a u32 const scalar.  Refill as u16.  Offset to skb->data", diff --git a/tools/testing/selftests/bpf/verifier/var_off.c b/tools/testing/selftests/bpf/verifier/var_off.c index d37f512fad16..b183e26c03f1 100644 --- a/tools/testing/selftests/bpf/verifier/var_off.c +++ b/tools/testing/selftests/bpf/verifier/var_off.c @@ -213,31 +213,6 @@  	.prog_type = BPF_PROG_TYPE_LWT_IN,  },  { -	"indirect variable-offset stack access, max_off+size > max_initialized", -	.insns = { -	/* Fill only the second from top 8 bytes of the stack. */ -	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), -	/* Get an unknown value. */ -	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0), -	/* Make it small and 4-byte aligned. */ -	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4), -	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16), -	/* Add it to fp.  We now have either fp-12 or fp-16, but we don't know -	 * which. fp-12 size 8 is partially uninitialized stack. -	 */ -	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10), -	/* Dereference it indirectly. */ -	BPF_LD_MAP_FD(BPF_REG_1, 0), -	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), -	BPF_MOV64_IMM(BPF_REG_0, 0), -	BPF_EXIT_INSN(), -	}, -	.fixup_map_hash_8b = { 5 }, -	.errstr = "invalid indirect read from stack R2 var_off", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_LWT_IN, -}, -{  	"indirect variable-offset stack access, min_off < min_initialized",  	.insns = {  	/* Fill only the top 8 bytes of the stack. */ @@ -290,33 +265,6 @@  	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,  },  { -	"indirect variable-offset stack access, uninitialized", -	.insns = { -	BPF_MOV64_IMM(BPF_REG_2, 6), -	BPF_MOV64_IMM(BPF_REG_3, 28), -	/* Fill the top 16 bytes of the stack. */ -	BPF_ST_MEM(BPF_W, BPF_REG_10, -16, 0), -	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), -	/* Get an unknown value. */ -	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 0), -	/* Make it small and 4-byte aligned. */ -	BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 4), -	BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16), -	/* Add it to fp.  We now have either fp-12 or fp-16, we don't know -	 * which, but either way it points to initialized stack. -	 */ -	BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10), -	BPF_MOV64_IMM(BPF_REG_5, 8), -	/* Dereference it indirectly. */ -	BPF_EMIT_CALL(BPF_FUNC_getsockopt), -	BPF_MOV64_IMM(BPF_REG_0, 0), -	BPF_EXIT_INSN(), -	}, -	.errstr = "invalid indirect read from stack R4 var_off", -	.result = REJECT, -	.prog_type = BPF_PROG_TYPE_SOCK_OPS, -}, -{  	"indirect variable-offset stack access, ok",  	.insns = {  	/* Fill the top 16 bytes of the stack. */ | 
