Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/bpf.h>
0003 #include <bpf/bpf_helpers.h>
0004 #include <bpf/bpf_tracing.h>
0005 #include <errno.h>
0006 
0007 char _license[] SEC("license") = "GPL";
0008 
0009 __u64 test1_result = 0;
0010 SEC("fentry/bpf_fentry_test1")
0011 int BPF_PROG(test1)
0012 {
0013     __u64 cnt = bpf_get_func_arg_cnt(ctx);
0014     __u64 a = 0, z = 0, ret = 0;
0015     __s64 err;
0016 
0017     test1_result = cnt == 1;
0018 
0019     /* valid arguments */
0020     err = bpf_get_func_arg(ctx, 0, &a);
0021 
0022     /* We need to cast access to traced function argument values with
0023      * proper type cast, because trampoline uses type specific instruction
0024      * to save it, like for 'int a' with 32-bit mov like:
0025      *
0026      *   mov %edi,-0x8(%rbp)
0027      *
0028      * so the upper 4 bytes are not zeroed.
0029      */
0030     test1_result &= err == 0 && ((int) a == 1);
0031 
0032     /* not valid argument */
0033     err = bpf_get_func_arg(ctx, 1, &z);
0034     test1_result &= err == -EINVAL;
0035 
0036     /* return value fails in fentry */
0037     err = bpf_get_func_ret(ctx, &ret);
0038     test1_result &= err == -EOPNOTSUPP;
0039     return 0;
0040 }
0041 
0042 __u64 test2_result = 0;
0043 SEC("fexit/bpf_fentry_test2")
0044 int BPF_PROG(test2)
0045 {
0046     __u64 cnt = bpf_get_func_arg_cnt(ctx);
0047     __u64 a = 0, b = 0, z = 0, ret = 0;
0048     __s64 err;
0049 
0050     test2_result = cnt == 2;
0051 
0052     /* valid arguments */
0053     err = bpf_get_func_arg(ctx, 0, &a);
0054     test2_result &= err == 0 && (int) a == 2;
0055 
0056     err = bpf_get_func_arg(ctx, 1, &b);
0057     test2_result &= err == 0 && b == 3;
0058 
0059     /* not valid argument */
0060     err = bpf_get_func_arg(ctx, 2, &z);
0061     test2_result &= err == -EINVAL;
0062 
0063     /* return value */
0064     err = bpf_get_func_ret(ctx, &ret);
0065     test2_result &= err == 0 && ret == 5;
0066     return 0;
0067 }
0068 
0069 __u64 test3_result = 0;
0070 SEC("fmod_ret/bpf_modify_return_test")
0071 int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret)
0072 {
0073     __u64 cnt = bpf_get_func_arg_cnt(ctx);
0074     __u64 a = 0, b = 0, z = 0, ret = 0;
0075     __s64 err;
0076 
0077     test3_result = cnt == 2;
0078 
0079     /* valid arguments */
0080     err = bpf_get_func_arg(ctx, 0, &a);
0081     test3_result &= err == 0 && ((int) a == 1);
0082 
0083     err = bpf_get_func_arg(ctx, 1, &b);
0084     test3_result &= err == 0 && ((int *) b == _b);
0085 
0086     /* not valid argument */
0087     err = bpf_get_func_arg(ctx, 2, &z);
0088     test3_result &= err == -EINVAL;
0089 
0090     /* return value */
0091     err = bpf_get_func_ret(ctx, &ret);
0092     test3_result &= err == 0 && ret == 0;
0093 
0094     /* change return value, it's checked in fexit_test program */
0095     return 1234;
0096 }
0097 
0098 __u64 test4_result = 0;
0099 SEC("fexit/bpf_modify_return_test")
0100 int BPF_PROG(fexit_test, int _a, int *_b, int _ret)
0101 {
0102     __u64 cnt = bpf_get_func_arg_cnt(ctx);
0103     __u64 a = 0, b = 0, z = 0, ret = 0;
0104     __s64 err;
0105 
0106     test4_result = cnt == 2;
0107 
0108     /* valid arguments */
0109     err = bpf_get_func_arg(ctx, 0, &a);
0110     test4_result &= err == 0 && ((int) a == 1);
0111 
0112     err = bpf_get_func_arg(ctx, 1, &b);
0113     test4_result &= err == 0 && ((int *) b == _b);
0114 
0115     /* not valid argument */
0116     err = bpf_get_func_arg(ctx, 2, &z);
0117     test4_result &= err == -EINVAL;
0118 
0119     /* return value */
0120     err = bpf_get_func_ret(ctx, &ret);
0121     test4_result &= err == 0 && ret == 1234;
0122     return 0;
0123 }