Reputation: 39
Using a eBPF lsm program, I trace file opening events for a specific container. Events are filtered by cgroups.
void handle_event(struct file *file, long ret, __u64 cgroup_id, void *ctx) {
struct event event = {};
event.pid = bpf_get_current_pid_tgid() >> 32;
event.uid = bpf_get_current_uid_gid();
event.cgroup = cgroup_id;
bpf_get_current_comm(&event.comm, sizeof(event.comm));
bpf_d_path(&file->f_path, event.fname, sizeof(event.fname));
// publish the event
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
}
In a first version, I attach filter the incoming events based on the cgroup of the current task:
SEC("lsm/file_open")
int BPF_PROG(file_open_lsm_in_bpf_cgroup_filtering, struct file *file, long ret){
__u64 cgroup_id = bpf_get_current_cgroup_id();
__u32 key = 0;
__u32 *cgroup_id_ptr = bpf_map_lookup_elem(&cgroups, &key);
if (cgroup_id_ptr && *cgroup_id_ptr == cgroup_id) {
handle_event(file, ret, cgroup_id, ctx);
}
return 0;
}
In a second version, I attach the same eBPF program to the target cgroup:
SEC("lsm_cgroup/file_open")
int BPF_PROG(file_open_lsm_pre_bpf_cgroup_filtering, struct file *file, long ret){
__u64 cgroup_id = bpf_get_current_cgroup_id();
handle_event(file, ret, cgroup_id, ctx);
return 0;
}
I observed a really strange behavior. With the above two program do not trace the log the same events (version 2 only logs about 10% of the logs logged by version 1). Now if I change the return value of version 2 to 1, as such:
SEC("lsm_cgroup/file_open")
int BPF_PROG(file_open_lsm_pre_bpf_cgroup_filtering, struct file *file, long ret){
__u64 cgroup_id = bpf_get_current_cgroup_id();
handle_event(file, ret, cgroup_id, ctx);
return 1;
}
Then, both programs have exactly the same output traces. How could this be possible? Which elements shall I investigate to troubleshoot this situation?
Upvotes: 0
Views: 20