125 lines · c
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 */10enum 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 18struct bpf_perf_link___local {19 struct bpf_link link;20 struct file *perf_file;21} __attribute__((preserve_access_index));22 23struct perf_event___local {24 u64 bpf_cookie;25} __attribute__((preserve_access_index));26 27enum bpf_link_type___local {28 BPF_LINK_TYPE_PERF_EVENT___local = 7,29};30 31extern const void bpf_link_fops __ksym;32extern const void bpf_link_fops_poll __ksym __weak;33extern const void bpf_map_fops __ksym;34extern const void bpf_prog_fops __ksym;35extern const void btf_fops __ksym;36 37const volatile enum bpf_obj_type obj_type = BPF_OBJ_UNKNOWN;38 39static __always_inline __u32 get_obj_id(void *ent, enum bpf_obj_type type)40{41 switch (type) {42 case BPF_OBJ_PROG:43 return BPF_CORE_READ((struct bpf_prog *)ent, aux, id);44 case BPF_OBJ_MAP:45 return BPF_CORE_READ((struct bpf_map *)ent, id);46 case BPF_OBJ_BTF:47 return BPF_CORE_READ((struct btf *)ent, id);48 case BPF_OBJ_LINK:49 return BPF_CORE_READ((struct bpf_link *)ent, id);50 default:51 return 0;52 }53}54 55/* could be used only with BPF_LINK_TYPE_PERF_EVENT links */56static __u64 get_bpf_cookie(struct bpf_link *link)57{58 struct bpf_perf_link___local *perf_link;59 struct perf_event___local *event;60 61 perf_link = container_of(link, struct bpf_perf_link___local, link);62 event = BPF_CORE_READ(perf_link, perf_file, private_data);63 return BPF_CORE_READ(event, bpf_cookie);64}65 66SEC("iter/task_file")67int iter(struct bpf_iter__task_file *ctx)68{69 struct file *file = ctx->file;70 struct task_struct *task = ctx->task;71 struct pid_iter_entry e;72 const void *fops;73 74 if (!file || !task)75 return 0;76 77 switch (obj_type) {78 case BPF_OBJ_PROG:79 fops = &bpf_prog_fops;80 break;81 case BPF_OBJ_MAP:82 fops = &bpf_map_fops;83 break;84 case BPF_OBJ_BTF:85 fops = &btf_fops;86 break;87 case BPF_OBJ_LINK:88 if (&bpf_link_fops_poll &&89 file->f_op == &bpf_link_fops_poll)90 fops = &bpf_link_fops_poll;91 else92 fops = &bpf_link_fops;93 break;94 default:95 return 0;96 }97 98 if (file->f_op != fops)99 return 0;100 101 __builtin_memset(&e, 0, sizeof(e));102 e.pid = task->tgid;103 e.id = get_obj_id(file->private_data, obj_type);104 105 if (obj_type == BPF_OBJ_LINK &&106 bpf_core_enum_value_exists(enum bpf_link_type___local,107 BPF_LINK_TYPE_PERF_EVENT___local)) {108 struct bpf_link *link = (struct bpf_link *) file->private_data;109 110 if (BPF_CORE_READ(link, type) == bpf_core_enum_value(enum bpf_link_type___local,111 BPF_LINK_TYPE_PERF_EVENT___local)) {112 e.has_bpf_cookie = true;113 e.bpf_cookie = get_bpf_cookie(link);114 }115 }116 117 bpf_probe_read_kernel_str(&e.comm, sizeof(e.comm),118 task->group_leader->comm);119 bpf_seq_write(ctx->meta->seq, &e, sizeof(e));120 121 return 0;122}123 124char LICENSE[] SEC("license") = "Dual BSD/GPL";125