selftest/bpf: Add test for var-offset stack access
Add a higher-level test (C BPF program) for the new functionality - variable access stack reads and writes. Signed-off-by: Andrei Matei <andreimatei1@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210207011027.676572-5-andreimatei1@gmail.com
This commit is contained in:
parent
7a22930c41
commit
0fd7562af1
35
tools/testing/selftests/bpf/prog_tests/stack_var_off.c
Normal file
35
tools/testing/selftests/bpf/prog_tests/stack_var_off.c
Normal file
@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <test_progs.h>
|
||||
#include "test_stack_var_off.skel.h"
|
||||
|
||||
/* Test read and writes to the stack performed with offsets that are not
|
||||
* statically known.
|
||||
*/
|
||||
void test_stack_var_off(void)
|
||||
{
|
||||
int duration = 0;
|
||||
struct test_stack_var_off *skel;
|
||||
|
||||
skel = test_stack_var_off__open_and_load();
|
||||
if (CHECK(!skel, "skel_open", "failed to open skeleton\n"))
|
||||
return;
|
||||
|
||||
/* Give pid to bpf prog so it doesn't trigger for anyone else. */
|
||||
skel->bss->test_pid = getpid();
|
||||
/* Initialize the probe's input. */
|
||||
skel->bss->input[0] = 2;
|
||||
skel->bss->input[1] = 42; /* This will be returned in probe_res. */
|
||||
|
||||
if (!ASSERT_OK(test_stack_var_off__attach(skel), "skel_attach"))
|
||||
goto cleanup;
|
||||
|
||||
/* Trigger probe. */
|
||||
usleep(1);
|
||||
|
||||
if (CHECK(skel->bss->probe_res != 42, "check_probe_res",
|
||||
"wrong probe res: %d\n", skel->bss->probe_res))
|
||||
goto cleanup;
|
||||
|
||||
cleanup:
|
||||
test_stack_var_off__destroy(skel);
|
||||
}
|
51
tools/testing/selftests/bpf/progs/test_stack_var_off.c
Normal file
51
tools/testing/selftests/bpf/progs/test_stack_var_off.c
Normal file
@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
int probe_res;
|
||||
|
||||
char input[4] = {};
|
||||
int test_pid;
|
||||
|
||||
SEC("tracepoint/syscalls/sys_enter_nanosleep")
|
||||
int probe(void *ctx)
|
||||
{
|
||||
/* This BPF program performs variable-offset reads and writes on a
|
||||
* stack-allocated buffer.
|
||||
*/
|
||||
char stack_buf[16];
|
||||
unsigned long len;
|
||||
unsigned long last;
|
||||
|
||||
if ((bpf_get_current_pid_tgid() >> 32) != test_pid)
|
||||
return 0;
|
||||
|
||||
/* Copy the input to the stack. */
|
||||
__builtin_memcpy(stack_buf, input, 4);
|
||||
|
||||
/* The first byte in the buffer indicates the length. */
|
||||
len = stack_buf[0] & 0xf;
|
||||
last = (len - 1) & 0xf;
|
||||
|
||||
/* Append something to the buffer. The offset where we write is not
|
||||
* statically known; this is a variable-offset stack write.
|
||||
*/
|
||||
stack_buf[len] = 42;
|
||||
|
||||
/* Index into the buffer at an unknown offset. This is a
|
||||
* variable-offset stack read.
|
||||
*
|
||||
* Note that if it wasn't for the preceding variable-offset write, this
|
||||
* read would be rejected because the stack slot cannot be verified as
|
||||
* being initialized. With the preceding variable-offset write, the
|
||||
* stack slot still cannot be verified, but the write inhibits the
|
||||
* respective check on the reasoning that, if there was a
|
||||
* variable-offset to a higher-or-equal spot, we're probably reading
|
||||
* what we just wrote.
|
||||
*/
|
||||
probe_res = stack_buf[last];
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
Loading…
x
Reference in New Issue
Block a user