0001
0002
0003 #include <vmlinux.h>
0004 #include <bpf/bpf_helpers.h>
0005 #include <bpf/bpf_core_read.h>
0006 #include <bpf/bpf_tracing.h>
0007 #include "pid_iter.h"
0008
0009
0010 enum bpf_obj_type {
0011 BPF_OBJ_UNKNOWN,
0012 BPF_OBJ_PROG,
0013 BPF_OBJ_MAP,
0014 BPF_OBJ_LINK,
0015 BPF_OBJ_BTF,
0016 };
0017
0018 extern const void bpf_link_fops __ksym;
0019 extern const void bpf_map_fops __ksym;
0020 extern const void bpf_prog_fops __ksym;
0021 extern const void btf_fops __ksym;
0022
0023 const volatile enum bpf_obj_type obj_type = BPF_OBJ_UNKNOWN;
0024
0025 static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)
0026 {
0027 switch (type) {
0028 case BPF_OBJ_PROG:
0029 return BPF_CORE_READ((struct bpf_prog *)ent, aux, id);
0030 case BPF_OBJ_MAP:
0031 return BPF_CORE_READ((struct bpf_map *)ent, id);
0032 case BPF_OBJ_BTF:
0033 return BPF_CORE_READ((struct btf *)ent, id);
0034 case BPF_OBJ_LINK:
0035 return BPF_CORE_READ((struct bpf_link *)ent, id);
0036 default:
0037 return 0;
0038 }
0039 }
0040
0041
0042 static __u64 get_bpf_cookie(struct bpf_link *link)
0043 {
0044 struct bpf_perf_link *perf_link;
0045 struct perf_event *event;
0046
0047 perf_link = container_of(link, struct bpf_perf_link, link);
0048 event = BPF_CORE_READ(perf_link, perf_file, private_data);
0049 return BPF_CORE_READ(event, bpf_cookie);
0050 }
0051
0052 SEC("iter/task_file")
0053 int iter(struct bpf_iter__task_file *ctx)
0054 {
0055 struct file *file = ctx->file;
0056 struct task_struct *task = ctx->task;
0057 struct pid_iter_entry e;
0058 const void *fops;
0059
0060 if (!file || !task)
0061 return 0;
0062
0063 switch (obj_type) {
0064 case BPF_OBJ_PROG:
0065 fops = &bpf_prog_fops;
0066 break;
0067 case BPF_OBJ_MAP:
0068 fops = &bpf_map_fops;
0069 break;
0070 case BPF_OBJ_BTF:
0071 fops = &btf_fops;
0072 break;
0073 case BPF_OBJ_LINK:
0074 fops = &bpf_link_fops;
0075 break;
0076 default:
0077 return 0;
0078 }
0079
0080 if (file->f_op != fops)
0081 return 0;
0082
0083 __builtin_memset(&e, 0, sizeof(e));
0084 e.pid = task->tgid;
0085 e.id = get_obj_id(file->private_data, obj_type);
0086
0087 if (obj_type == BPF_OBJ_LINK) {
0088 struct bpf_link *link = (struct bpf_link *) file->private_data;
0089
0090 if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) {
0091 e.has_bpf_cookie = true;
0092 e.bpf_cookie = get_bpf_cookie(link);
0093 }
0094 }
0095
0096 bpf_probe_read_kernel_str(&e.comm, sizeof(e.comm),
0097 task->group_leader->comm);
0098 bpf_seq_write(ctx->meta->seq, &e, sizeof(e));
0099
0100 return 0;
0101 }
0102
0103 char LICENSE[] SEC("license") = "Dual BSD/GPL";