Skip to content

Commit 253558e

Browse files
Avoid taskstats_exit and sched_process_exit
taskstats_exit can be compiled out based on kernel configuration. Instead use disassociate_ctty(1) as an indication that group_dead has been set. sched_process_exit is called before exit_files, so it's possible that a socket disconnect event could be emitted after a process termination. instead use exit_task_namespaces to emit the exit event. we had little choice in the matter since sched_process_exit is executed before disassociate_ctty, but sched_process_exit was still the incorrect spot to emit an exit event and worth noting.
1 parent 497c829 commit 253558e

2 files changed

Lines changed: 38 additions & 13 deletions

File tree

GPL/Events/Process/Probe.bpf.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,20 +195,42 @@ int BPF_PROG(sched_process_exec,
195195
// The problem is taskstats_exit__enter happens before file descriptors are
196196
// closed in exit_files(), so instead of emiting the event here, record that we
197197
// saw group_dead and delay emiting the event until sched_process_exit().
198-
static int taskstats_exit__enter(const struct task_struct *task, int group_dead)
198+
//
199+
// UPDATE: taskstats_exit can be compiled out of the kernel based on configuration.
200+
// So, instead we use disassociate_ctty and exit_task_namespaces which are always
201+
// present. disassociate_ctty is called from do_exit() only when group_dead is true,
202+
// and in that case, the parameter, on_exit, is set to true. exit_task_namespaces
203+
// is called after diassociate_ctty in do_exit() unconditionally, so we can use it to
204+
// emit the event if we "saw" group_dead, i.e. disassociate_ctty was called.
205+
// Finally, sched_process_exit() is not called after exit_files, but exit_task_namespaces
206+
// is.
207+
static int disassociate_ctty__enter(int on_exit)
199208
{
200209
struct ebpf_events_state state = {};
210+
const struct task_struct *task = (struct task_struct *)bpf_get_current_task();
201211

202-
if (!group_dead || is_kernel_thread(task))
212+
if (!on_exit || is_kernel_thread(task))
203213
return 0;
204214

205215
ebpf_events_state__set(EBPF_EVENTS_STATE_GROUP_DEAD, &state);
206216

207217
return 0;
208218
}
209219

210-
SEC("tp_btf/sched_process_exit")
211-
int BPF_PROG(sched_process_exit, const struct task_struct *task)
220+
SEC("fentry/disassociate_ctty")
221+
int BPF_PROG(fentry__disassociate_ctty, int on_exit)
222+
{
223+
return disassociate_ctty__enter(on_exit);
224+
}
225+
226+
227+
SEC("kprobe/disassociate_ctty")
228+
int BPF_KPROBE(kprobe__disassociate_ctty, int on_exit)
229+
{
230+
return disassociate_ctty__enter(on_exit);
231+
}
232+
233+
static int exit_task_namespaces__enter(const struct task_struct *task)
212234
{
213235
struct ebpf_process_exit_event *event;
214236

@@ -247,18 +269,19 @@ int BPF_PROG(sched_process_exit, const struct task_struct *task)
247269
return 0;
248270
}
249271

250-
SEC("fentry/taskstats_exit")
251-
int BPF_PROG(fentry__taskstats_exit, const struct task_struct *task, int group_dead)
272+
SEC("fentry/exit_task_namespaces")
273+
int BPF_PROG(fentry__exit_task_namespaces, const struct task_struct *task)
252274
{
253-
return taskstats_exit__enter(task, group_dead);
275+
return exit_task_namespaces__enter(task);
254276
}
255277

256-
SEC("kprobe/taskstats_exit")
257-
int BPF_KPROBE(kprobe__taskstats_exit, const struct task_struct *task, int group_dead)
278+
SEC("kprobe/exit_task_namespaces")
279+
int BPF_KPROBE(kprobe__exit_task_namespaces, const struct task_struct *task)
258280
{
259-
return taskstats_exit__enter(task, group_dead);
281+
return exit_task_namespaces__enter(task);
260282
}
261283

284+
262285
// tracepoint/syscalls/sys_[enter/exit]_[name] tracepoints are not available
263286
// with BTF type information, so we must use a non-BTF tracepoint
264287
SEC("tracepoint/syscalls/sys_exit_setsid")

non-GPL/Events/Lib/EbpfEvents.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,8 @@ static int probe_set_autoload(struct btf *btf, struct EventProbe_bpf *obj, uint6
381381
err = err ?: bpf_program__set_autoload(obj->progs.kretprobe__do_filp_open, false);
382382
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__vfs_rename, false);
383383
err = err ?: bpf_program__set_autoload(obj->progs.kretprobe__vfs_rename, false);
384-
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__taskstats_exit, false);
384+
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__disassociate_ctty, false);
385+
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__exit_task_namespaces, false);
385386
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__commit_creds, false);
386387
err = err ?: bpf_program__set_autoload(obj->progs.kretprobe__inet_csk_accept, false);
387388
err = err ?: bpf_program__set_autoload(obj->progs.kprobe__tcp_v4_connect, false);
@@ -403,7 +404,8 @@ static int probe_set_autoload(struct btf *btf, struct EventProbe_bpf *obj, uint6
403404
err = err ?: bpf_program__set_autoload(obj->progs.fexit__do_filp_open, false);
404405
err = err ?: bpf_program__set_autoload(obj->progs.fentry__vfs_rename, false);
405406
err = err ?: bpf_program__set_autoload(obj->progs.fexit__vfs_rename, false);
406-
err = err ?: bpf_program__set_autoload(obj->progs.fentry__taskstats_exit, false);
407+
err = err ?: bpf_program__set_autoload(obj->progs.fentry__disassociate_ctty, false);
408+
err = err ?: bpf_program__set_autoload(obj->progs.fentry__exit_task_namespaces, false);
407409
err = err ?: bpf_program__set_autoload(obj->progs.fentry__commit_creds, false);
408410
err = err ?: bpf_program__set_autoload(obj->progs.fexit__inet_csk_accept, false);
409411
err = err ?: bpf_program__set_autoload(obj->progs.fexit__tcp_v4_connect, false);
@@ -473,7 +475,7 @@ static bool system_has_bpf_tramp(void)
473475
{.code = BPF_EXIT | BPF_JMP, .dst_reg = 0, .src_reg = 0, .off = 0, .imm = 0}};
474476
int insns_cnt = 2;
475477

476-
btf_id = btf__find_by_name(btf, "taskstats_exit");
478+
btf_id = btf__find_by_name(btf, "disassociate_ctty");
477479
LIBBPF_OPTS(bpf_prog_load_opts, opts, .log_buf = NULL, .log_level = 0,
478480
.expected_attach_type = BPF_TRACE_FENTRY, .attach_btf_id = btf_id);
479481
prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACING, NULL, "GPL", insns, insns_cnt, &opts);

0 commit comments

Comments
 (0)