mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
selftests/bpf: Add exception tests with stack arguments
Add tests to verify that bpf_throw() correctly unwinds the stack when the program uses outgoing stack arguments (functions with >5 args). Without the preceding x86 fix, these tests crash the kernel on x86 due to corrupted callee-saved register restore. There is no change for arm64 to support exception with stack arguments. Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20260517150707.289273-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
18a37465b0
commit
576482b55c
|
|
@ -85,6 +85,13 @@ static void test_exceptions_success(void)
|
|||
RUN_SUCCESS(exception_bad_assert_range_with, 10);
|
||||
RUN_SUCCESS(exception_throw_from_void_global, 11);
|
||||
|
||||
if (skel->rodata->has_stack_arg) {
|
||||
RUN_SUCCESS(exception_throw_stack_arg, 56);
|
||||
RUN_SUCCESS(exception_throw_after_stack_arg, 56);
|
||||
RUN_SUCCESS(exception_throw_subprog_stack_arg, 56);
|
||||
RUN_SUCCESS(exception_throw_subprog_after_stack_arg, 56);
|
||||
}
|
||||
|
||||
#define RUN_EXT(load_ret, attach_err, expr, msg, after_link) \
|
||||
{ \
|
||||
LIBBPF_OPTS(bpf_object_open_opts, o, .kernel_log_buf = log_buf, \
|
||||
|
|
|
|||
|
|
@ -379,4 +379,118 @@ int exception_bad_assert_range_with(struct __sk_buff *ctx)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \
|
||||
&& defined(__BPF_FEATURE_STACK_ARGUMENT)
|
||||
|
||||
const volatile bool has_stack_arg = true;
|
||||
|
||||
long arg1 = 1, arg2 = 2, arg3 = 3, arg4 = 4, arg5 = 5;
|
||||
long arg6 = 6, arg7 = 7, arg8 = 8, arg9 = 9, arg10 = 10;
|
||||
|
||||
__noinline static long throwing_many_args(long a, long b, long c, long d,
|
||||
long e, long f, long g, long h,
|
||||
long i, long j)
|
||||
{
|
||||
bpf_throw(a + b + c + d + e + f + g + h + i + j);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline int exception_cb_sa(u64 cookie)
|
||||
{
|
||||
return cookie + 1;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
__exception_cb(exception_cb_sa)
|
||||
int exception_throw_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
throwing_many_args(arg1, arg2, arg3, arg4, arg5,
|
||||
arg6, arg7, arg8, arg9, arg10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline static long no_throw_many_args(long a, long b, long c, long d,
|
||||
long e, long f, long g, long h,
|
||||
long i, long j)
|
||||
{
|
||||
return a + b + c + d + e + f + g + h + i + j;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
__exception_cb(exception_cb_sa)
|
||||
int exception_throw_after_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = no_throw_many_args(arg1, arg2, arg3, arg4, arg5,
|
||||
arg6, arg7, arg8, arg9, arg10);
|
||||
if (ret > 0)
|
||||
bpf_throw(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline static long subprog_throw_sa(long val)
|
||||
{
|
||||
throwing_many_args(val, val + 1, val + 2, val + 3, val + 4,
|
||||
val + 5, val + 6, val + 7, val + 8, val + 9);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
__exception_cb(exception_cb_sa)
|
||||
int exception_throw_subprog_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
subprog_throw_sa(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__noinline static long subprog_throw_after_sa(long val)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = no_throw_many_args(val, val + 1, val + 2, val + 3, val + 4,
|
||||
val + 5, val + 6, val + 7, val + 8, val + 9);
|
||||
if (ret > 0)
|
||||
bpf_throw(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
__exception_cb(exception_cb_sa)
|
||||
int exception_throw_subprog_after_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
subprog_throw_after_sa(arg1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const volatile bool has_stack_arg = false;
|
||||
|
||||
SEC("tc")
|
||||
int exception_throw_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int exception_throw_after_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int exception_throw_subprog_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SEC("tc")
|
||||
int exception_throw_subprog_after_stack_arg(struct __sk_buff *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user