Skip to content

Commit

Permalink
feature(events): turn SchedProcessXXX control plane enabled
Browse files Browse the repository at this point in the history
- ADD parent_start_time argument to event context (*)

- move functions containing inline asm to the end of their files
- create buffer_memcpy() for map-to-map buffer copy in ebpf

- sched_process_fork:
  - create a signal handler for a SchedProcessFork signal event
  - only SUBMIT the SchedProcessFork event if picked by a policy
  - ALWAYS submit the SchedProcessFork signal event (args only)

- sched_process_exec:
  - create a signal handler for a SchedProcessExec signal event
  - only SUBMIT the SchedProcessExec event if picked by a policy
  - ALWAYS submit the SchedProcessFork signal event (args only)

- sched_process_exit:
  - create a signal handler for a SchedProcessExit signal event
  - only SUBMIT the SchedProcessExit event if picked by a policy
  - ALWAYS submit the SchedProcessExit signal event (args only)
  - The SchedProcessExit signal event has extra 2 arguments added,
    both will be needed for the process tree implementation.

- create a list of essential events coming from the control plane
  package, instead of a function within Tracee type.

- add a 'Control' boolean to EventState to control whether the
  event, and its dependant events, should only be configured
  because of the control plane. This is needed because some
  events are too complex to have duplicated probes (they involve
  having tailCalls and other dependencies), so the same event
  probes are used to submit the regular AND the signal events.

(*) parent_start_time argument to event context:

  The reason to have parent start time argument added is to have an unique
  identifier, using 'host_tid' + 'process start time' (using the murmur3
  hashing function), on each submitted event. This way, the process tree
  is able to identify process parent using the process hash (and each ever
  existing process node entry in the process tree is hashed and unique).

  => The reasoning will be cleared in next commits.

NOTE: There are NO logical changes to eBPF code but to copy the scratch
buffer and submit it into the signal events perfbuffer.
  • Loading branch information
rafaeldtinoco committed Aug 4, 2023
1 parent 6839ba7 commit 4bb81ad
Show file tree
Hide file tree
Showing 9 changed files with 614 additions and 215 deletions.
104 changes: 58 additions & 46 deletions pkg/ebpf/c/common/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ statfunc int save_u64_arr_to_buf(args_buffer_t *, const u64 __user *, int, u8);
statfunc int save_str_arr_to_buf(args_buffer_t *, const char __user *const __user *, u8);
statfunc int save_args_str_arr_to_buf(args_buffer_t *, const char *, const char *, int, u8);
statfunc int save_sockaddr_to_buf(args_buffer_t *, struct socket *, u8);
statfunc int save_args_to_submit_buf(event_data_t *, args_t *);
statfunc void *buffer_memcpy(void *, const void *, size_t);
statfunc int events_perf_submit(program_data_t *, u32 id, long);
statfunc int signal_perf_submit(void *, controlplane_signal_t *sig, u32 id);
statfunc int save_args_to_submit_buf(event_data_t *, args_t *);

// FUNCTIONS

Expand Down Expand Up @@ -336,51 +337,6 @@ statfunc int save_sockaddr_to_buf(args_buffer_t *buf, struct socket *sock, u8 in
return 0;
}

statfunc int events_perf_submit(program_data_t *p, u32 id, long ret)
{
p->event->context.eventid = id;
p->event->context.retval = ret;

// KEEP THIS FOR DEBUGGING (until process tree is fully implemented)
// u32 hash = (u64) hash_u32_and_u64(p->event->context.task.pid, p->event->context.task.task_start_time);
// bpf_printk("hash: %u\n", hash);

// Get Stack trace
if (p->config->options & OPT_CAPTURE_STACK_TRACES) {
int stack_id = bpf_get_stackid(p->ctx, &stack_addresses, BPF_F_USER_STACK);
if (stack_id >= 0) {
p->event->context.stack_id = stack_id;
}
}

u32 size = sizeof(event_context_t) + sizeof(u8) +
p->event->args_buf.offset; // context + argnum + arg buffer size

// inline bounds check to force compiler to use the register of size
asm volatile("if %[size] < %[max_size] goto +1;\n"
"%[size] = %[max_size];\n"
:
: [size] "r"(size), [max_size] "i"(MAX_EVENT_SIZE));

return bpf_perf_event_output(p->ctx, &events, BPF_F_CURRENT_CPU, p->event, size);
}

statfunc int signal_perf_submit(void *ctx, controlplane_signal_t *sig, u32 id)
{
sig->event_id = id;

u32 size =
sizeof(u32) + sizeof(u8) + sig->args_buf.offset; // signal id + argnum + arg buffer size

// inline bounds check to force compiler to use the register of size
asm volatile("if %[size] < %[max_size] goto +1;\n"
"%[size] = %[max_size];\n"
:
: [size] "r"(size), [max_size] "i"(MAX_SIGNAL_SIZE));

return bpf_perf_event_output(ctx, &signals, BPF_F_CURRENT_CPU, sig, size);
}

#define DEC_ARG(n, enc_arg) ((enc_arg >> (8 * n)) & 0xFF)

statfunc int save_args_to_submit_buf(event_data_t *event, args_t *args)
Expand Down Expand Up @@ -488,4 +444,60 @@ statfunc int save_args_to_submit_buf(event_data_t *event, args_t *args)
return arg_num;
}

statfunc void *buffer_memcpy(void *dest, const void *src, size_t n)
{
u8 *cdest = (u8 *) dest;
const u8 *csrc = (const u8 *) src;

for (size_t i = 0; i < n; i++) {
cdest[i] = csrc[i];
}

return dest;
}

// ATTENTION: Keep the embedded asm code at the end due to parsing errors (vscode) after they
// happen.

statfunc int events_perf_submit(program_data_t *p, u32 id, long ret)
{
p->event->context.eventid = id;
p->event->context.retval = ret;

// Get Stack trace
if (p->config->options & OPT_CAPTURE_STACK_TRACES) {
int stack_id = bpf_get_stackid(p->ctx, &stack_addresses, BPF_F_USER_STACK);
if (stack_id >= 0) {
p->event->context.stack_id = stack_id;
}
}

// context + argnum + arg buffer size
u32 size = sizeof(event_context_t) + sizeof(u8) + p->event->args_buf.offset;

// inline bounds check to force compiler to use the register of size
asm volatile("if %[size] < %[max_size] goto +1;\n"
"%[size] = %[max_size];\n"
:
: [size] "r"(size), [max_size] "i"(MAX_EVENT_SIZE));

return bpf_perf_event_output(p->ctx, &events, BPF_F_CURRENT_CPU, p->event, size);
}

statfunc int signal_perf_submit(void *ctx, controlplane_signal_t *sig, u32 id)
{
sig->event_id = id;

// signal id + argnum + arg buffer size
u32 size = sizeof(u32) + sizeof(u8) + sig->args_buf.offset;

// inline bounds check to force compiler to use the register of size
asm volatile("if %[size] < %[max_size] goto +1;\n"
"%[size] = %[max_size];\n"
:
: [size] "r"(size), [max_size] "i"(MAX_SIGNAL_SIZE));

return bpf_perf_event_output(ctx, &signals, BPF_F_CURRENT_CPU, sig, size);
}

#endif

0 comments on commit 4bb81ad

Please sign in to comment.