forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'bpf: Allow reads from uninit stack'
Eduard Zingerman says: ==================== This patch-set modifies BPF verifier to accept programs that read from uninitialized stack locations, but only if executed in privileged mode. This provides significant verification performance gains: 30% to 70% less processed states for big number of test programs. The reason for performance gains comes from treating STACK_MISC and STACK_INVALID as compatible, when cached state is compared to current state in verifier.c:stacksafe(). The change should not affect safety, because any value read from STACK_MISC location has full binary range (e.g. 0x00-0xff for byte-sized reads). Details and measurements are provided in the description for the patch #1. The change was suggested by Andrii Nakryiko, the initial patch was created by Alexei Starovoitov. The discussion could be found at [1]. Changes v1 -> v2 (v1 available at [2]): - Calls to helper functions now convert STACK_INVALID to STACK_MISC (suggested by Andrii); - The test case progs/test_global_func10.c is updated to expect new error message. Before recent commit [3] exact content of error messages was not verified for this test. - Replaced incorrect '//'-style comments in test case asm blocks by '/*...*/'-style comments in order to fix compilation issues; - Changed the tag from "Suggested-By" to "Co-developed-by" for Alexei on patch #1, please let me know if this is appropriate use of the tag. [1] https://lore.kernel.org/bpf/CAADnVQKs2i1iuZ5SUGuJtxWVfGYR9kDgYKhq3rNV+kBLQCu7rA@mail.gmail.com/ [2] https://lore.kernel.org/bpf/20230216183606.2483834-1-eddyz87@gmail.com/ [3] 95ebb37 ("selftests/bpf: Convert test_global_funcs test to test_loader framework") ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
- Loading branch information
Showing
11 changed files
with
204 additions
and
136 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
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,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); | ||
} |
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
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,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"; |
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
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
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
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
Oops, something went wrong.