summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/bpf/progs/verifier_kfunc_uninit_multi.c
blob: ab3bb81a11fd29ac7576ee66859cd76cedd3713d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "../test_kmods/bpf_testmod_kfunc.h"

/* Keep the kfunc BTF records used by the inline assembly. */
void __kfunc_btf_root(void)
{
	asm volatile ("" :
		: "r"(&bpf_kfunc_test_uninit_multi),
		  "r"(&bpf_kfunc_test_uninit_pair),
		  "r"(&bpf_kfunc_test_uninit_stack));
}

SEC("tc")
__success __retval(42)
__flag(BPF_F_TEST_STATE_FREQ)
__caps_unpriv(CAP_BPF | CAP_NET_ADMIN)
__prepare_priv
__success_unpriv
__naked void multiple_outputs(void)
{
	asm volatile (
		"*(u64 *)(r10 - 16) = 0;"
		"*(u64 *)(r10 - 8) = 0;"
		"goto +0;"
		"r1 = r10;"
		"r1 += -16;"
		"r2 = r10;"
		"r2 += -8;"
		"r3 = 8;"
		"call %[bpf_kfunc_test_uninit_multi];"
		"r0 = *(u32 *)(r10 - 16);"
		"r1 = *(u32 *)(r10 - 8);"
		"if r1 != 0x2a2a2a2a goto 1f;"
		"r1 = *(u32 *)(r10 - 4);"
		"if r1 == 0x2a2a2a2a goto 2f;"
	"1:;"
		"r0 = 0;"
	"2:;"
		"exit;"
		: : __imm(bpf_kfunc_test_uninit_multi) : __clobber_all);
}

SEC("tc")
__success __retval(42)
__caps_unpriv(CAP_BPF | CAP_NET_ADMIN)
__prepare_priv
__failure_unpriv __msg_unpriv("invalid read from stack off -16+0 size 4")
__naked void variable_size_preserves_other_output(void)
{
	asm volatile (
		"r3 = *(u32 *)(r1 + 0);"
		"r3 &= 7;"
		"*(u64 *)(r10 - 8) = 0;"
		"r1 = r10;"
		"r1 += -16;"
		"r2 = r10;"
		"r2 += -8;"
		"call %[bpf_kfunc_test_uninit_multi];"
		"r0 = *(u32 *)(r10 - 16);"
		"exit;"
		: : __imm(bpf_kfunc_test_uninit_multi) : __clobber_all);
}

SEC("tc")
__arch_x86_64 __arch_arm64
__success __retval(42)
__caps_unpriv(CAP_BPF | CAP_NET_ADMIN)
__prepare_priv
__failure_unpriv __msg_unpriv("invalid read from stack off -8+0 size 4")
__naked void output_after_by_value_argument(void)
{
	asm volatile (
		"r1 = 20;"
		"r2 = 22;"
		"r3 = r10;"
		"r3 += -8;"
		"call %[bpf_kfunc_test_uninit_pair];"
		"r0 = *(u32 *)(r10 - 8);"
		"exit;"
		: : __imm(bpf_kfunc_test_uninit_pair) : __clobber_all);
}

#if defined(__BPF_FEATURE_STACK_ARGUMENT)
SEC("tc")
__arch_x86_64 __arch_arm64 __arch_riscv64
__success __retval(15)
__caps_unpriv(CAP_BPF | CAP_NET_ADMIN)
__prepare_priv
__failure_unpriv __msg_unpriv("invalid read from stack off -8+0 size 4")
__naked void output_passed_on_stack(void)
{
	asm volatile (
		"r1 = 1;"
		"r2 = 2;"
		"r3 = 3;"
		"r4 = 4;"
		"r5 = 5;"
		"r6 = r10;"
		"r6 += -8;"
		"*(u64 *)(r11 - 8) = r6;"
		"call %[bpf_kfunc_test_uninit_stack];"
		"r0 = *(u32 *)(r10 - 8);"
		"exit;"
		: : __imm(bpf_kfunc_test_uninit_stack) : __clobber_all);
}
#endif

char _license[] SEC("license") = "GPL";