-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Andrei Matei
authored and
Alexei Starovoitov
committed
Feb 10, 2021
1 parent
7a22930
commit 0fd7562
Showing
2 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"; |