0001
0002
0003
0004 #include <string.h>
0005 #include <linux/bpf.h>
0006 #include <bpf/bpf_helpers.h>
0007 #include "bpf_misc.h"
0008 #include "errno.h"
0009
0010 char _license[] SEC("license") = "GPL";
0011
0012 int pid, err, val;
0013
0014 struct sample {
0015 int pid;
0016 int seq;
0017 long value;
0018 char comm[16];
0019 };
0020
0021 struct {
0022 __uint(type, BPF_MAP_TYPE_RINGBUF);
0023 } ringbuf SEC(".maps");
0024
0025 struct {
0026 __uint(type, BPF_MAP_TYPE_ARRAY);
0027 __uint(max_entries, 1);
0028 __type(key, __u32);
0029 __type(value, __u32);
0030 } array_map SEC(".maps");
0031
0032 SEC("tp/syscalls/sys_enter_nanosleep")
0033 int test_read_write(void *ctx)
0034 {
0035 char write_data[64] = "hello there, world!!";
0036 char read_data[64] = {}, buf[64] = {};
0037 struct bpf_dynptr ptr;
0038 int i;
0039
0040 if (bpf_get_current_pid_tgid() >> 32 != pid)
0041 return 0;
0042
0043 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(write_data), 0, &ptr);
0044
0045
0046 err = bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
0047
0048
0049 err = err ?: bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
0050
0051
0052 for (i = 0; i < sizeof(read_data); i++) {
0053 if (read_data[i] != write_data[i]) {
0054 err = 1;
0055 break;
0056 }
0057 }
0058
0059 bpf_ringbuf_discard_dynptr(&ptr, 0);
0060 return 0;
0061 }
0062
0063 SEC("tp/syscalls/sys_enter_nanosleep")
0064 int test_data_slice(void *ctx)
0065 {
0066 __u32 key = 0, val = 235, *map_val;
0067 struct bpf_dynptr ptr;
0068 __u32 map_val_size;
0069 void *data;
0070
0071 map_val_size = sizeof(*map_val);
0072
0073 if (bpf_get_current_pid_tgid() >> 32 != pid)
0074 return 0;
0075
0076 bpf_map_update_elem(&array_map, &key, &val, 0);
0077
0078 map_val = bpf_map_lookup_elem(&array_map, &key);
0079 if (!map_val) {
0080 err = 1;
0081 return 0;
0082 }
0083
0084 bpf_dynptr_from_mem(map_val, map_val_size, 0, &ptr);
0085
0086
0087 data = bpf_dynptr_data(&ptr, map_val_size + 1, 1);
0088 if (data) {
0089 err = 2;
0090 return 0;
0091 }
0092
0093
0094 data = bpf_dynptr_data(&ptr, 0, map_val_size + 1);
0095 if (data) {
0096 err = 3;
0097 return 0;
0098 }
0099
0100 data = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
0101 if (!data) {
0102 err = 4;
0103 return 0;
0104 }
0105
0106 *(__u32 *)data = 999;
0107
0108 err = bpf_probe_read_kernel(&val, sizeof(val), data);
0109 if (err)
0110 return 0;
0111
0112 if (val != *(int *)data)
0113 err = 5;
0114
0115 return 0;
0116 }
0117
0118 static int ringbuf_callback(__u32 index, void *data)
0119 {
0120 struct sample *sample;
0121
0122 struct bpf_dynptr *ptr = (struct bpf_dynptr *)data;
0123
0124 sample = bpf_dynptr_data(ptr, 0, sizeof(*sample));
0125 if (!sample)
0126 err = 2;
0127 else
0128 sample->pid += index;
0129
0130 return 0;
0131 }
0132
0133 SEC("tp/syscalls/sys_enter_nanosleep")
0134 int test_ringbuf(void *ctx)
0135 {
0136 struct bpf_dynptr ptr;
0137 struct sample *sample;
0138
0139 if (bpf_get_current_pid_tgid() >> 32 != pid)
0140 return 0;
0141
0142 val = 100;
0143
0144
0145 err = bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
0146
0147 sample = err ? NULL : bpf_dynptr_data(&ptr, 0, sizeof(*sample));
0148 if (!sample) {
0149 err = 1;
0150 goto done;
0151 }
0152
0153 sample->pid = 10;
0154
0155
0156 bpf_loop(10, ringbuf_callback, &ptr, 0);
0157
0158 if (sample->pid != 55)
0159 err = 2;
0160
0161 done:
0162 bpf_ringbuf_discard_dynptr(&ptr, 0);
0163 return 0;
0164 }