1 // SPDX-License-Identifier: GPL-2.0 2 #include <vmlinux.h> 3 #include <bpf/bpf_helpers.h> 4 #include <bpf/bpf_tracing.h> 5 #include <errno.h> 6 7 char _license[] SEC("license") = "GPL"; 8 9 __u64 test1_result = 0; 10 SEC("fentry/bpf_fentry_test1") 11 int BPF_PROG(test1) 12 { 13 __u64 cnt = bpf_get_func_arg_cnt(ctx); 14 __u64 a = 0, z = 0, ret = 0; 15 __s64 err; 16 17 test1_result = cnt == 1; 18 19 /* valid arguments */ 20 err = bpf_get_func_arg(ctx, 0, &a); 21 22 /* We need to cast access to traced function argument values with 23 * proper type cast, because trampoline uses type specific instruction 24 * to save it, like for 'int a' with 32-bit mov like: 25 * 26 * mov %edi,-0x8(%rbp) 27 * 28 * so the upper 4 bytes are not zeroed. 29 */ 30 test1_result &= err == 0 && ((int) a == 1); 31 32 /* not valid argument */ 33 err = bpf_get_func_arg(ctx, 1, &z); 34 test1_result &= err == -EINVAL; 35 36 /* return value fails in fentry */ 37 err = bpf_get_func_ret(ctx, &ret); 38 test1_result &= err == -EOPNOTSUPP; 39 return 0; 40 } 41 42 __u64 test2_result = 0; 43 SEC("fexit/bpf_fentry_test2") 44 int BPF_PROG(test2) 45 { 46 __u64 cnt = bpf_get_func_arg_cnt(ctx); 47 __u64 a = 0, b = 0, z = 0, ret = 0; 48 __s64 err; 49 50 test2_result = cnt == 2; 51 52 /* valid arguments */ 53 err = bpf_get_func_arg(ctx, 0, &a); 54 test2_result &= err == 0 && (int) a == 2; 55 56 err = bpf_get_func_arg(ctx, 1, &b); 57 test2_result &= err == 0 && b == 3; 58 59 /* not valid argument */ 60 err = bpf_get_func_arg(ctx, 2, &z); 61 test2_result &= err == -EINVAL; 62 63 /* return value */ 64 err = bpf_get_func_ret(ctx, &ret); 65 test2_result &= err == 0 && ret == 5; 66 return 0; 67 } 68 69 __u64 test3_result = 0; 70 SEC("fmod_ret/bpf_modify_return_test") 71 int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret) 72 { 73 __u64 cnt = bpf_get_func_arg_cnt(ctx); 74 __u64 a = 0, b = 0, z = 0, ret = 0; 75 __s64 err; 76 77 test3_result = cnt == 2; 78 79 /* valid arguments */ 80 err = bpf_get_func_arg(ctx, 0, &a); 81 test3_result &= err == 0 && ((int) a == 1); 82 83 err = bpf_get_func_arg(ctx, 1, &b); 84 test3_result &= err == 0 && ((int *) b == _b); 85 86 /* not valid argument */ 87 err = bpf_get_func_arg(ctx, 2, &z); 88 test3_result &= err == -EINVAL; 89 90 /* return value */ 91 err = bpf_get_func_ret(ctx, &ret); 92 test3_result &= err == 0 && ret == 0; 93 94 /* change return value, it's checked in fexit_test program */ 95 return 1234; 96 } 97 98 __u64 test4_result = 0; 99 SEC("fexit/bpf_modify_return_test") 100 int BPF_PROG(fexit_test, int _a, int *_b, int _ret) 101 { 102 __u64 cnt = bpf_get_func_arg_cnt(ctx); 103 __u64 a = 0, b = 0, z = 0, ret = 0; 104 __s64 err; 105 106 test4_result = cnt == 2; 107 108 /* valid arguments */ 109 err = bpf_get_func_arg(ctx, 0, &a); 110 test4_result &= err == 0 && ((int) a == 1); 111 112 err = bpf_get_func_arg(ctx, 1, &b); 113 test4_result &= err == 0 && ((int *) b == _b); 114 115 /* not valid argument */ 116 err = bpf_get_func_arg(ctx, 2, &z); 117 test4_result &= err == -EINVAL; 118 119 /* return value */ 120 err = bpf_get_func_ret(ctx, &ret); 121 test4_result &= err == 0 && ret == 1234; 122 return 0; 123 } 124 125 __u64 test5_result = 0; 126 SEC("tp_btf/bpf_testmod_fentry_test1_tp") 127 int BPF_PROG(tp_test1) 128 { 129 __u64 cnt = bpf_get_func_arg_cnt(ctx); 130 __u64 a = 0, z = 0; 131 __s64 err; 132 133 test5_result = cnt == 1; 134 135 err = bpf_get_func_arg(ctx, 0, &a); 136 test5_result &= err == 0 && ((int) a == 1); 137 138 /* not valid argument */ 139 err = bpf_get_func_arg(ctx, 1, &z); 140 test5_result &= err == -EINVAL; 141 142 return 0; 143 } 144 145 __u64 test6_result = 0; 146 SEC("tp_btf/bpf_testmod_fentry_test2_tp") 147 int BPF_PROG(tp_test2) 148 { 149 __u64 cnt = bpf_get_func_arg_cnt(ctx); 150 __u64 a = 0, b = 0, z = 0; 151 __s64 err; 152 153 test6_result = cnt == 2; 154 155 /* valid arguments */ 156 err = bpf_get_func_arg(ctx, 0, &a); 157 test6_result &= err == 0 && (int) a == 2; 158 159 err = bpf_get_func_arg(ctx, 1, &b); 160 test6_result &= err == 0 && b == 3; 161 162 /* not valid argument */ 163 err = bpf_get_func_arg(ctx, 2, &z); 164 test6_result &= err == -EINVAL; 165 166 return 0; 167 } 168 169 __u64 test7_result = 0; 170 #if defined(bpf_target_x86) || defined(bpf_target_arm64) 171 SEC("fsession/bpf_fentry_test1") 172 int BPF_PROG(test7) 173 { 174 __u64 cnt = bpf_get_func_arg_cnt(ctx); 175 __u64 a = 0, z = 0, ret = 0; 176 __s64 err; 177 178 test7_result = cnt == 1; 179 180 /* valid arguments */ 181 err = bpf_get_func_arg(ctx, 0, &a); 182 test7_result &= err == 0 && ((int) a == 1); 183 184 /* not valid argument */ 185 err = bpf_get_func_arg(ctx, 1, &z); 186 test7_result &= err == -EINVAL; 187 188 if (bpf_session_is_return(ctx)) { 189 err = bpf_get_func_ret(ctx, &ret); 190 test7_result &= err == 0 && ret == 2; 191 } else { 192 err = bpf_get_func_ret(ctx, &ret); 193 test7_result &= err == 0 && ret == 0; 194 } 195 196 return 0; 197 } 198 #else 199 SEC("fentry/bpf_fentry_test1") 200 int BPF_PROG(test7) 201 { 202 test7_result = 1; 203 return 0; 204 } 205 #endif 206