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