1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 /* Copyright (c) 2020 Facebook */ 3 #include <vmlinux.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_core_read.h> 6 #include <bpf/bpf_tracing.h> 7 #include "pid_iter.h" 8 9 /* keep in sync with the definition in main.h */ 10 enum bpf_obj_type { 11 BPF_OBJ_UNKNOWN, 12 BPF_OBJ_PROG, 13 BPF_OBJ_MAP, 14 BPF_OBJ_LINK, 15 BPF_OBJ_BTF, 16 }; 17 18 extern const void bpf_link_fops __ksym; 19 extern const void bpf_map_fops __ksym; 20 extern const void bpf_prog_fops __ksym; 21 extern const void btf_fops __ksym; 22 23 const volatile enum bpf_obj_type obj_type = BPF_OBJ_UNKNOWN; 24 25 static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type) 26 { 27 switch (type) { 28 case BPF_OBJ_PROG: 29 return BPF_CORE_READ((struct bpf_prog *)ent, aux, id); 30 case BPF_OBJ_MAP: 31 return BPF_CORE_READ((struct bpf_map *)ent, id); 32 case BPF_OBJ_BTF: 33 return BPF_CORE_READ((struct btf *)ent, id); 34 case BPF_OBJ_LINK: 35 return BPF_CORE_READ((struct bpf_link *)ent, id); 36 default: 37 return 0; 38 } 39 } 40 41 /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */ 42 static __u64 get_bpf_cookie(struct bpf_link *link) 43 { 44 struct bpf_perf_link *perf_link; 45 struct perf_event *event; 46 47 perf_link = container_of(link, struct bpf_perf_link, link); 48 event = BPF_CORE_READ(perf_link, perf_file, private_data); 49 return BPF_CORE_READ(event, bpf_cookie); 50 } 51 52 SEC("iter/task_file") 53 int iter(struct bpf_iter__task_file *ctx) 54 { 55 struct file *file = ctx->file; 56 struct task_struct *task = ctx->task; 57 struct pid_iter_entry e; 58 const void *fops; 59 60 if (!file || !task) 61 return 0; 62 63 switch (obj_type) { 64 case BPF_OBJ_PROG: 65 fops = &bpf_prog_fops; 66 break; 67 case BPF_OBJ_MAP: 68 fops = &bpf_map_fops; 69 break; 70 case BPF_OBJ_BTF: 71 fops = &btf_fops; 72 break; 73 case BPF_OBJ_LINK: 74 fops = &bpf_link_fops; 75 break; 76 default: 77 return 0; 78 } 79 80 if (file->f_op != fops) 81 return 0; 82 83 __builtin_memset(&e, 0, sizeof(e)); 84 e.pid = task->tgid; 85 e.id = get_obj_id(file->private_data, obj_type); 86 87 if (obj_type == BPF_OBJ_LINK) { 88 struct bpf_link *link = (struct bpf_link *) file->private_data; 89 90 if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) { 91 e.has_bpf_cookie = true; 92 e.bpf_cookie = get_bpf_cookie(link); 93 } 94 } 95 96 bpf_probe_read_kernel_str(&e.comm, sizeof(e.comm), 97 task->group_leader->comm); 98 bpf_seq_write(ctx->meta->seq, &e, sizeof(e)); 99 100 return 0; 101 } 102 103 char LICENSE[] SEC("license") = "Dual BSD/GPL"; 104