3
#include <bpf/bpf_helpers.h>
4
#include <bpf/bpf_core_read.h>
5
#ifdef __TARGET_ARCH_arm64
6
#include <bpf/bpf_tracing.h>
9
#include <gadget/mntns_filter.h>
11
#include <gadget/filesystem.h>
16
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
18
const volatile bool ignore_failed = true;
19
const volatile uid_t targ_uid = INVALID_UID;
20
const volatile int max_args = DEFAULT_MAXARGS;
22
static const struct event empty_event = {};
25
__uint(type, BPF_MAP_TYPE_HASH);
27
__uint(max_entries, 1024);
29
__uint(max_entries, 10240);
32
__type(value, struct event);
36
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
37
__uint(key_size, sizeof(u32));
38
__uint(value_size, sizeof(u32));
65
__uint(type, BPF_MAP_TYPE_HASH);
68
__uint(max_entries, 1024);
69
} pid_by_tgid SEC(".maps");
71
static __always_inline bool valid_uid(uid_t uid)
73
return uid != INVALID_UID;
76
SEC("tracepoint/syscalls/sys_enter_execve")
77
int ig_execve_e(struct trace_event_raw_sys_enter *ctx)
86
struct task_struct *task;
88
const char **args = (const char **)(ctx->args[1]);
92
u64 uid_gid = bpf_get_current_uid_gid();
93
u32 uid = (u32)uid_gid;
94
u32 gid = (u32)(uid_gid >> 32);
96
if (valid_uid(targ_uid) && targ_uid != uid)
99
task = (struct task_struct *)bpf_get_current_task();
100
mntns_id = (u64)BPF_CORE_READ(task, nsproxy, mnt_ns, ns.inum);
102
if (gadget_should_discard_mntns_id(mntns_id))
105
id = bpf_get_current_pid_tgid();
108
if (bpf_map_update_elem(&execs, &pid, &empty_event, BPF_NOEXIST))
111
event = bpf_map_lookup_elem(&execs, &pid);
115
bpf_map_update_elem(&pid_by_tgid, &tgid, &zero64, BPF_NOEXIST);
117
pid_sum = bpf_map_lookup_elem(&pid_by_tgid, &tgid);
121
__atomic_add_fetch(pid_sum, (u64)pid, __ATOMIC_RELAXED);
123
event->timestamp = bpf_ktime_get_boot_ns();
128
if (bpf_core_field_exists(task->loginuid))
129
event->loginuid = BPF_CORE_READ(task, loginuid.val);
131
event->loginuid = 4294967295;
133
if (bpf_core_field_exists(task->sessionid))
134
event->sessionid = BPF_CORE_READ(task, sessionid);
136
event->ppid = (pid_t)BPF_CORE_READ(task, real_parent, tgid);
137
event->args_count = 0;
138
event->args_size = 0;
139
event->mntns_id = mntns_id;
142
fs = BPF_CORE_READ(task, fs);
143
cwd = get_path_str(&fs->pwd);
144
bpf_probe_read_kernel_str(event->cwd, MAX_STRING_SIZE, cwd);
147
ret = bpf_probe_read_user_str(event->args, ARGSIZE,
148
(const char *)ctx->args[0]);
149
if (ret <= ARGSIZE) {
150
event->args_size += ret;
153
event->args[0] = '\0';
159
for (i = 1; i < TOTAL_MAX_ARGS && i < max_args; i++) {
160
bpf_probe_read_user(&argp, sizeof(argp), &args[i]);
164
if (event->args_size > LAST_ARG)
167
ret = bpf_probe_read_user_str(&event->args[event->args_size],
173
event->args_size += ret;
176
bpf_probe_read_user(&argp, sizeof(argp), &args[max_args]);
185
static __always_inline bool has_upper_layer()
187
struct task_struct *task = (struct task_struct *)bpf_get_current_task();
188
struct inode *inode = BPF_CORE_READ(task, mm, exe_file, f_inode);
192
unsigned long sb_magic = BPF_CORE_READ(inode, i_sb, s_magic);
194
if (sb_magic != OVERLAYFS_SUPER_MAGIC) {
198
struct dentry *upperdentry;
205
bpf_probe_read_kernel(&upperdentry, sizeof(upperdentry),
207
bpf_core_type_size(struct inode));
208
return upperdentry != NULL;
211
SEC("tracepoint/syscalls/sys_exit_execve")
212
int ig_execve_x(struct trace_event_raw_sys_exit *ctx)
216
pid_t execs_lookup_key;
220
u32 uid = (u32)bpf_get_current_uid_gid();
222
if (valid_uid(targ_uid) && targ_uid != uid)
224
id = bpf_get_current_pid_tgid();
229
pid_sum = bpf_map_lookup_elem(&pid_by_tgid, &tgid);
235
execs_lookup_key = (ret == 0) ? (pid_t)*pid_sum : pid;
236
event = bpf_map_lookup_elem(&execs, &execs_lookup_key);
240
__atomic_add_fetch(pid_sum, (u64)-pid, __ATOMIC_RELAXED);
241
if (*pid_sum == 0 || ret == 0)
242
bpf_map_delete_elem(&pid_by_tgid, &tgid);
246
if (ignore_failed && ret < 0)
250
event->upper_layer = has_upper_layer();
254
bpf_get_current_comm(&event->comm, sizeof(event->comm));
255
size_t len = EVENT_SIZE(event);
256
if (len <= sizeof(*event))
257
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event,
260
bpf_map_delete_elem(&execs, &execs_lookup_key);
264
char LICENSE[] SEC("license") = "GPL";