github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/ebpftracer/c/headers/common/context.h (about) 1 #ifndef __COMMON_CONTEXT_H__ 2 #define __COMMON_CONTEXT_H__ 3 4 #include <vmlinux.h> 5 6 #include <common/logging.h> 7 #include <common/task.h> 8 #include <common/cgroups.h> 9 #include <common/pid_translation.h> 10 11 // PROTOTYPES 12 13 statfunc int init_task_context(task_context_t *, struct task_struct *, u32); 14 statfunc void init_proc_info_scratch(u32, scratch_t *); 15 statfunc proc_info_t *init_proc_info(u32, u32); 16 statfunc void init_task_info_scratch(u32, scratch_t *); 17 statfunc task_info_t *init_task_info(u32, u32); 18 statfunc bool context_changed(task_context_t *, task_context_t *); 19 statfunc int init_program_data(program_data_t *, void *); 20 statfunc int init_tailcall_program_data(program_data_t *, void *); 21 statfunc void reset_event_args(program_data_t *); 22 23 // FUNCTIONS 24 25 statfunc int init_task_context(task_context_t *tsk_ctx, struct task_struct *task, u32 options) 26 { 27 // NOTE: parent is always a real process, not a potential thread group leader 28 struct task_struct *leader = get_leader_task(task); 29 struct task_struct *up_parent = get_leader_task(get_parent_task(leader)); 30 31 // Task Info on Host 32 tsk_ctx->host_ppid = get_task_pid(up_parent); // always a real process (not a lwp) 33 // Namespaces Info 34 tsk_ctx->tid = get_task_ns_pid(task); 35 tsk_ctx->pid = get_task_ns_tgid(task); 36 37 u32 task_pidns_id = get_task_pid_ns_id(task); 38 u32 up_parent_pidns_id = get_task_pid_ns_id(up_parent); 39 get_pid_in_ns(global_config.pid_ns_id, &tsk_ctx->node_host_pid); 40 41 if (task_pidns_id == up_parent_pidns_id) 42 tsk_ctx->ppid = get_task_ns_pid(up_parent); // e.g: pid 1 will have nsppid 0 43 44 tsk_ctx->pid_id = task_pidns_id; 45 tsk_ctx->mnt_id = get_task_mnt_ns_id(task); 46 // User Info 47 tsk_ctx->uid = bpf_get_current_uid_gid(); 48 // Times 49 tsk_ctx->start_time = get_task_start_time(task); 50 tsk_ctx->leader_start_time = get_task_start_time(leader); 51 tsk_ctx->parent_start_time = get_task_start_time(up_parent); 52 53 if (is_compat(task)) 54 tsk_ctx->flags |= IS_COMPAT_FLAG; 55 56 // Program name 57 bpf_get_current_comm(&tsk_ctx->comm, sizeof(tsk_ctx->comm)); 58 59 // UTS Name 60 char *uts_name = get_task_uts_name(task); 61 if (uts_name) 62 bpf_probe_read_kernel_str(&tsk_ctx->uts_name, TASK_COMM_LEN, uts_name); 63 64 return 0; 65 } 66 67 statfunc void init_proc_info_scratch(u32 pid, scratch_t *scratch) 68 { 69 __builtin_memset(&scratch->proc_info, 0, sizeof(proc_info_t)); 70 bpf_map_update_elem(&proc_info_map, &pid, &scratch->proc_info, BPF_NOEXIST); 71 } 72 73 statfunc proc_info_t *init_proc_info(u32 pid, u32 scratch_idx) 74 { 75 scratch_t *scratch = bpf_map_lookup_elem(&scratch_map, &scratch_idx); 76 if (unlikely(scratch == NULL)) 77 return NULL; 78 79 init_proc_info_scratch(pid, scratch); 80 81 return bpf_map_lookup_elem(&proc_info_map, &pid); 82 } 83 84 statfunc void init_task_info_scratch(u32 tid, scratch_t *scratch) 85 { 86 __builtin_memset(&scratch->task_info, 0, sizeof(task_info_t)); 87 bpf_map_update_elem(&task_info_map, &tid, &scratch->task_info, BPF_NOEXIST); 88 } 89 90 statfunc task_info_t *init_task_info(u32 tid, u32 scratch_idx) 91 { 92 scratch_t *scratch = bpf_map_lookup_elem(&scratch_map, &scratch_idx); 93 if (unlikely(scratch == NULL)) 94 return NULL; 95 96 init_task_info_scratch(tid, scratch); 97 98 return bpf_map_lookup_elem(&task_info_map, &tid); 99 } 100 101 // clang-format off 102 statfunc int init_program_data(program_data_t *p, void *ctx) 103 { 104 int zero = 0; 105 106 p->ctx = ctx; 107 108 // allow caller to specify a stack/map based event_data_t pointer 109 if (p->event == NULL) { 110 p->event = bpf_map_lookup_elem(&event_data_map, &zero); 111 if (unlikely(p->event == NULL)) 112 return 0; 113 } 114 115 p->config = bpf_map_lookup_elem(&config_map, &zero); 116 if (unlikely(p->config == NULL)) 117 return 0; 118 119 p->event->args_buf.offset = 0; 120 p->event->args_buf.argnum = 0; 121 p->task = (struct task_struct *) bpf_get_current_task(); 122 123 __builtin_memset(&p->event->context.task, 0, sizeof(p->event->context.task)); 124 125 // get the minimal context required at this stage 126 // any other context will be initialized only if event is submitted 127 u64 id = bpf_get_current_pid_tgid(); 128 p->event->context.task.host_tid = id; 129 p->event->context.task.host_pid = id >> 32; 130 p->event->context.ts = bpf_ktime_get_ns(); 131 p->event->context.processor_id = (u16) bpf_get_smp_processor_id(); 132 p->event->context.syscall = get_task_syscall_id(p->task); 133 134 u32 host_pid = p->event->context.task.host_pid; 135 p->proc_info = bpf_map_lookup_elem(&proc_info_map, &host_pid); 136 if (unlikely(p->proc_info == NULL)) { 137 p->proc_info = init_proc_info(host_pid, p->scratch_idx); 138 if (unlikely(p->proc_info == NULL)) 139 return 0; 140 } 141 142 u32 host_tid = p->event->context.task.host_tid; 143 p->task_info = bpf_map_lookup_elem(&task_info_map, &host_tid); 144 if (unlikely(p->task_info == NULL)) { 145 p->task_info = init_task_info(host_tid, p->scratch_idx); 146 if (unlikely(p->task_info == NULL)) 147 return 0; 148 149 init_task_context(&p->task_info->context, p->task, p->config->options); 150 } 151 152 if (p->config->options & OPT_CGROUP_V1) { 153 p->event->context.task.cgroup_id = get_cgroup_v1_subsys0_id(p->task); 154 } else { 155 p->event->context.task.cgroup_id = bpf_get_current_cgroup_id(); 156 } 157 p->task_info->context.cgroup_id = p->event->context.task.cgroup_id; 158 u32 cgroup_id_lsb = p->event->context.task.cgroup_id; 159 u8 *state = bpf_map_lookup_elem(&containers_map, &cgroup_id_lsb); 160 if (state != NULL) { 161 p->task_info->container_state = *state; 162 switch (*state) { 163 case CONTAINER_STARTED: 164 case CONTAINER_EXISTED: 165 p->event->context.task.flags |= CONTAINER_STARTED_FLAG; 166 } 167 } 168 169 // initialize matched_policies to all policies match 170 p->event->context.matched_policies = ~0ULL; 171 172 return 1; 173 } 174 // clang-format on 175 176 statfunc int init_tailcall_program_data(program_data_t *p, void *ctx) 177 { 178 u32 zero = 0; 179 180 p->ctx = ctx; 181 182 p->event = bpf_map_lookup_elem(&event_data_map, &zero); 183 if (unlikely(p->event == NULL)) 184 return 0; 185 186 p->config = bpf_map_lookup_elem(&config_map, &zero); 187 if (unlikely(p->config == NULL)) 188 return 0; 189 190 p->task_info = bpf_map_lookup_elem(&task_info_map, &p->event->context.task.host_tid); 191 if (unlikely(p->task_info == NULL)) { 192 return 0; 193 } 194 195 p->proc_info = bpf_map_lookup_elem(&proc_info_map, &p->event->context.task.host_pid); 196 if (unlikely(p->proc_info == NULL)) { 197 return 0; 198 } 199 200 return 1; 201 } 202 203 // use this function for programs that send more than one event 204 statfunc void reset_event_args(program_data_t *p) 205 { 206 p->event->args_buf.offset = 0; 207 p->event->args_buf.argnum = 0; 208 } 209 210 #endif