Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix proc info lru #3918

Merged
merged 3 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions pkg/ebpf/c/common/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
// PROTOTYPES

statfunc int init_context(void *, event_context_t *, struct task_struct *, u32);
statfunc task_info_t *init_task_info(u32, u32, scratch_t *);
statfunc void init_proc_info_scratch(u32, scratch_t *);
statfunc proc_info_t *init_proc_info(u32, u32);
statfunc void init_task_info_scratch(u32, scratch_t *);
statfunc task_info_t *init_task_info(u32, u32);
statfunc bool context_changed(task_context_t *, task_context_t *);
statfunc int init_program_data(program_data_t *, void *);
statfunc int init_tailcall_program_data(program_data_t *, void *);
Expand Down Expand Up @@ -90,31 +93,38 @@ init_context(void *ctx, event_context_t *context, struct task_struct *task, u32
return 0;
}

statfunc task_info_t *init_task_info(u32 tid, u32 pid, scratch_t *scratch)
statfunc void init_proc_info_scratch(u32 pid, scratch_t *scratch)
{
int zero = 0;
__builtin_memset(&scratch->proc_info, 0, sizeof(proc_info_t));
bpf_map_update_elem(&proc_info_map, &pid, &scratch->proc_info, BPF_NOEXIST);
}

// allow caller to specify a stack/map based scratch_t pointer
if (scratch == NULL) {
scratch = bpf_map_lookup_elem(&scratch_map, &zero);
if (unlikely(scratch == NULL))
return NULL;
}
statfunc proc_info_t *init_proc_info(u32 pid, u32 scratch_idx)
{
scratch_t *scratch = bpf_map_lookup_elem(&scratch_map, &scratch_idx);
if (unlikely(scratch == NULL))
return NULL;

proc_info_t *proc_info = bpf_map_lookup_elem(&proc_info_map, &pid);
if (proc_info == NULL) {
scratch->proc_info.new_proc = false;
scratch->proc_info.follow_in_scopes = 0;
scratch->proc_info.binary.mnt_id = 0;
scratch->proc_info.binary_no_mnt = 0;
__builtin_memset(scratch->proc_info.binary.path, 0, MAX_BIN_PATH_SIZE);
bpf_map_update_elem(&proc_info_map, &pid, &scratch->proc_info, BPF_NOEXIST);
}
init_proc_info_scratch(pid, scratch);

return bpf_map_lookup_elem(&proc_info_map, &pid);
}

statfunc void init_task_info_scratch(u32 tid, scratch_t *scratch)
{
scratch->task_info.syscall_traced = false;
scratch->task_info.recompute_scope = true;
scratch->task_info.container_state = CONTAINER_UNKNOWN;
bpf_map_update_elem(&task_info_map, &tid, &scratch->task_info, BPF_NOEXIST);
}

statfunc task_info_t *init_task_info(u32 tid, u32 scratch_idx)
{
scratch_t *scratch = bpf_map_lookup_elem(&scratch_map, &scratch_idx);
if (unlikely(scratch == NULL))
return NULL;

init_task_info_scratch(tid, scratch);

return bpf_map_lookup_elem(&task_info_map, &tid);
}
Expand Down Expand Up @@ -160,16 +170,21 @@ statfunc int init_program_data(program_data_t *p, void *ctx)

bool container_lookup_required = true;

p->task_info = bpf_map_lookup_elem(&task_info_map, &p->event->context.task.host_tid);
u32 host_pid = p->event->context.task.host_pid;
p->proc_info = bpf_map_lookup_elem(&proc_info_map, &host_pid);
if (unlikely(p->proc_info == NULL)) {
p->proc_info = init_proc_info(host_pid, p->scratch_idx);
if (unlikely(p->proc_info == NULL))
return 0;
}

u32 host_tid = p->event->context.task.host_tid;
p->task_info = bpf_map_lookup_elem(&task_info_map, &host_tid);
if (unlikely(p->task_info == NULL)) {
p->task_info = init_task_info(
p->event->context.task.host_tid,
p->event->context.task.host_pid,
p->scratch
);
if (unlikely(p->task_info == NULL)) {
p->task_info = init_task_info(host_tid, p->scratch_idx);
if (unlikely(p->task_info == NULL))
return 0;
}

// just initialized task info: recompute_scope is already set to true
goto out;
}
Expand Down
11 changes: 2 additions & 9 deletions pkg/ebpf/c/common/filtering.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,10 @@ statfunc u64 compute_scopes(program_data_t *p)
task_context_t *context = &p->task_info->context;

// Don't monitor self
if (p->config->tracee_pid == context->host_pid) {
if (p->config->tracee_pid == context->host_pid)
return 0;
}

proc_info_t *proc_info = bpf_map_lookup_elem(&proc_info_map, &context->host_pid);
if (unlikely(proc_info == NULL)) {
// entry should exist in proc_map (init_program_data should have set it otherwise)
// disable logging as a workaround for instruction limit verifier error on kernel 4.19
// tracee_log(p->event->ctx, BPF_LOG_LVL_WARN, BPF_LOG_ID_MAP_LOOKUP_ELEM, 0);
return 0;
}
proc_info_t *proc_info = p->proc_info;

policies_config_t *policies_cfg = get_policies_config(p);
if (unlikely(policies_cfg == NULL)) {
Expand Down
7 changes: 0 additions & 7 deletions pkg/ebpf/c/common/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,6 @@ struct {

// scratch area

struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1); // simultaneous softirqs running per CPU (?)
__type(key, u32); // per cpu index ... (always zero)
__type(value, scratch_t); // ... linked to a scratch area
} net_heap_scratch SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1); // simultaneous softirqs running per CPU (?)
Expand Down
4 changes: 2 additions & 2 deletions pkg/ebpf/c/maps.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ typedef struct sys_32_to_64_map sys_32_to_64_map_t;
// holds data for every process
struct proc_info_map {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 10240);
__uint(max_entries, 30720);
__type(key, u32);
__type(value, proc_info_t);
} proc_info_map SEC(".maps");
Expand Down Expand Up @@ -331,7 +331,7 @@ typedef struct logs_count logs_count_t;
// scratch space to avoid allocating stuff on the stack
struct scratch_map {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1);
__uint(max_entries, 2);
__type(key, u32);
__type(value, scratch_t);
} scratch_map SEC(".maps");
Expand Down
49 changes: 16 additions & 33 deletions pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,9 @@ int sys_enter_init(struct bpf_raw_tracepoint_args *ctx)
u32 tid = pid_tgid;
task_info_t *task_info = bpf_map_lookup_elem(&task_info_map, &tid);
if (unlikely(task_info == NULL)) {
u32 pid = pid_tgid >> 32;
task_info = init_task_info(tid, pid, NULL);
if (unlikely(task_info == NULL)) {
task_info = init_task_info(tid, 0);
if (unlikely(task_info == NULL))
return 0;
}
}

syscall_data_t *sys = &(task_info->syscall_data);
Expand Down Expand Up @@ -209,11 +207,9 @@ int sys_exit_init(struct bpf_raw_tracepoint_args *ctx)
u32 tid = pid_tgid;
task_info_t *task_info = bpf_map_lookup_elem(&task_info_map, &tid);
if (unlikely(task_info == NULL)) {
u32 pid = pid_tgid >> 32;
task_info = init_task_info(tid, pid, NULL);
if (unlikely(task_info == NULL)) {
task_info = init_task_info(tid, 0);
if (unlikely(task_info == NULL))
return 0;
}
}

// check if syscall is being traced and mark that it finished
Expand Down Expand Up @@ -532,7 +528,7 @@ int tracepoint__sched__sched_process_fork(struct bpf_raw_tracepoint_args *ctx)
return 0;
}

// Copy the parent's proc_info to the child's enty.
// Copy the parent's proc_info to the child's entry.
bpf_map_update_elem(&proc_info_map, &child_pid, p_proc_info, BPF_NOEXIST);
c_proc_info = bpf_map_lookup_elem(&proc_info_map, &child_pid);
if (unlikely(c_proc_info == NULL)) {
Expand Down Expand Up @@ -1226,14 +1222,7 @@ int tracepoint__sched__sched_process_exec(struct bpf_raw_tracepoint_args *ctx)
struct file *file = get_file_ptr_from_bprm(bprm);
void *file_path = get_path_str(__builtin_preserve_access_index(&file->f_path));

// Pick data about the process from proc_info_map
proc_info_t *proc_info = bpf_map_lookup_elem(&proc_info_map, &p.event->context.task.host_pid);
if (proc_info == NULL) {
// init_program_data should have created an entry in proc_info_map for this pid
tracee_log(ctx, BPF_LOG_LVL_WARN, BPF_LOG_ID_MAP_LOOKUP_ELEM, 0);
return 0;
}

proc_info_t *proc_info = p.proc_info;
proc_info->new_proc = true; // task has started after tracee started running

// Extract the binary name to be used in should_trace
Expand Down Expand Up @@ -4487,12 +4476,7 @@ int BPF_KPROBE(trace_load_elf_phdrs)
if (!should_trace((&p)))
return 0;

proc_info_t *proc_info = bpf_map_lookup_elem(&proc_info_map, &p.event->context.task.host_pid);
if (unlikely(proc_info == NULL)) {
// entry should exist in proc_map (init_program_data should have set it otherwise)
tracee_log(ctx, BPF_LOG_LVL_WARN, BPF_LOG_ID_MAP_LOOKUP_ELEM, 0);
return 0;
}
proc_info_t *proc_info = p.proc_info;

struct file *loaded_elf = (struct file *) PT_REGS_PARM2(ctx);
const char *elf_pathname = (char *) get_path_str(__builtin_preserve_access_index(&loaded_elf->f_path));
Expand Down Expand Up @@ -5785,14 +5769,8 @@ int BPF_KPROBE(cgroup_bpf_run_filter_skb)
if (unlikely(e == NULL))
return 0;

scratch_t *s = bpf_map_lookup_elem(&net_heap_scratch, &zero);
if (unlikely(s == NULL))
return 0;

program_data_t p = {
.event = e,
.scratch = s,
};
program_data_t p = {};
p.scratch_idx = 1;
if (!init_program_data(&p, ctx))
return 0;

Expand Down Expand Up @@ -6710,8 +6688,13 @@ int sched_process_exec_signal(struct bpf_raw_tracepoint_args *ctx)
// Pick the interpreter path from the proc_info map, which is set by the "load_elf_phdrs".
u32 host_pid = get_task_host_tgid(task);
proc_info_t *proc_info = bpf_map_lookup_elem(&proc_info_map, &host_pid);
if (proc_info == NULL)
return 0;
if (proc_info == NULL) {
proc_info = init_proc_info(host_pid, 0);
if (unlikely(proc_info == NULL)) {
tracee_log(ctx, BPF_LOG_LVL_WARN, BPF_LOG_ID_MAP_LOOKUP_ELEM, 0);
return 0;
}
}

struct file *file = get_file_ptr_from_bprm(bprm);
void *file_path = get_path_str(__builtin_preserve_access_index(&file->f_path));
Expand Down
3 changes: 2 additions & 1 deletion pkg/ebpf/c/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,9 @@ typedef union scratch {
typedef struct program_data {
config_entry_t *config;
task_info_t *task_info;
proc_info_t *proc_info;
event_data_t *event;
scratch_t *scratch;
u32 scratch_idx;
void *ctx;
} program_data_t;

Expand Down
Loading