2
from __future__ import print_function
15
from collections import defaultdict
16
from datetime import datetime
17
from time import strftime
20
#include <uapi/linux/ptrace.h>
21
#include <linux/sched.h>
32
char comm[TASK_COMM_LEN];
36
BPF_PERF_OUTPUT(events);
38
TRACEPOINT_PROBE(sched, sched_process_exit)
40
struct task_struct *task = (typeof(task))bpf_get_current_task();
41
if (task->pid != task->tgid) { return 0; }
43
struct data_t data = {};
45
data.start_time = task->start_time,
46
data.exit_time = bpf_ktime_get_ns(),
48
data.ppid = task->real_parent->tgid,
49
bpf_get_current_comm(&data.comm, sizeof(data.comm));
51
events.perf_submit(args, &data, sizeof(data));
55
static int __submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
57
bpf_probe_read_user(data->argv, sizeof(data->argv), ptr);
58
events.perf_submit(ctx, data, sizeof(struct data_t));
62
static int submit_arg(struct pt_regs *ctx, void *ptr, struct data_t *data)
64
const char *argp = NULL;
65
bpf_probe_read_user(&argp, sizeof(argp), ptr);
67
return __submit_arg(ctx, (void *)(argp), data);
72
int syscall__execve(struct pt_regs *ctx,
73
const char __user *filename,
74
const char __user *const __user *__argv,
75
const char __user *const __user *__envp)
78
struct task_struct *task = (typeof(task))bpf_get_current_task();
80
struct data_t data = {};
81
data.pid = bpf_get_current_pid_tgid() >> 32;
84
bpf_get_current_comm(&data.comm, sizeof(data.comm));
85
__submit_arg(ctx, (void *)filename, &data);
87
// skip first arg, as we submitted filename
89
for (int i = 1; i < MAXARG; i++) {
90
if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
94
// handle truncated argument list
95
char ellipsis[] = "...";
96
__submit_arg(ctx, (void *)ellipsis, &data);
102
int do_ret_sys_execve(struct pt_regs *ctx)
104
struct task_struct *task = (typeof(task))bpf_get_current_task();
106
struct data_t data = {};
107
data.pid = bpf_get_current_pid_tgid() >> 32;
108
bpf_get_current_comm(&data.comm, sizeof(data.comm));
109
events.perf_submit(ctx, &data, sizeof(data));
115
print("%-16s %-7s %-7s %-7s %s" %
116
("PCOMM", "PID", "PPID", "AGE(ms)", "ARGV"))
119
pidToArgv = defaultdict(list)
121
def _print_event(cpu, data, size):
122
"""Print the exit event."""
124
e = buffer["events"].event(data)
126
comm = e.comm.decode()
132
pidToArgv[e.pid].append(e.argv)
135
if comm not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]:
137
del(pidToArgv[e.pid])
142
age = (e.exit_time - e.start_time) / 1e6
143
argv = b' '.join(pidToArgv[e.pid]).replace(b'\n', b'\\n')
144
print("%-16s %-7d %-7d %-7.2f %s" %
145
(comm, e.pid, e.ppid, age, argv.decode()), end="")
149
del(pidToArgv[e.pid])
153
def snoop(bpf, event_handler):
154
bpf["events"].open_perf_buffer(event_handler)
156
bpf.perf_buffer_poll()
161
buffer = BPF(text=bpf_src)
162
execve_fnname = buffer.get_syscall_fnname("execve")
163
buffer.attach_kprobe(event=execve_fnname, fn_name="syscall__execve")
165
snoop(buffer, _print_event)
166
except KeyboardInterrupt:
172
if __name__ == '__main__':