5
#include <bpf/bpf_helpers.h>
6
#include <bpf/bpf_core_read.h>
7
#include <gadget/mntns_filter.h>
8
#include <gadget/filesystem.h>
11
#define NR_MAX_PREFIX_FILTER 255
14
const volatile pid_t targ_pid = 0;
15
const volatile pid_t targ_tgid = 0;
16
const volatile uid_t targ_uid = INVALID_UID;
17
const volatile bool targ_failed = false;
18
const volatile bool get_full_path = false;
19
const volatile __u32 prefixes_nr = 0;
22
const struct event *unusedevent __attribute__((unused));
25
__uint(type, BPF_MAP_TYPE_HASH);
26
__uint(max_entries, 10240);
28
__type(value, struct start_t);
32
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
33
__uint(key_size, sizeof(u32));
34
__uint(value_size, sizeof(u32));
38
__uint(type, BPF_MAP_TYPE_LPM_TRIE);
39
__type(key, struct prefix_key);
41
__uint(map_flags, BPF_F_NO_PREALLOC);
42
__uint(max_entries, NR_MAX_PREFIX_FILTER);
43
} prefixes SEC(".maps");
46
__uint(type, BPF_MAP_TYPE_HASH);
47
__uint(max_entries, 1024);
49
__type(value, struct prefix_key);
50
} prefix_keys SEC(".maps");
53
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
54
__uint(max_entries, 1);
56
__type(value, struct event);
57
} empty_event SEC(".maps");
59
static const struct prefix_key empty_prefix_key = {};
61
static __always_inline bool valid_uid(uid_t uid)
63
return uid != INVALID_UID;
66
static __always_inline bool trace_allowed(u32 tgid, u32 pid,
73
if (targ_tgid && targ_tgid != tgid)
75
if (targ_pid && targ_pid != pid)
77
if (valid_uid(targ_uid)) {
78
uid = (u32)bpf_get_current_uid_gid();
79
if (targ_uid != uid) {
85
struct prefix_key *key;
94
if (bpf_map_update_elem(&prefix_keys, &pid, &empty_prefix_key,
98
key = bpf_map_lookup_elem(&prefix_keys, &pid);
112
key->prefixlen = sizeof(key->filename) * CHAR_BIT;
113
__builtin_memcpy(key->filename, filename,
114
sizeof(key->filename));
116
found = bpf_map_lookup_elem(&prefixes, key) != NULL;
118
bpf_map_delete_elem(&prefix_keys, &pid);
123
mntns_id = gadget_get_mntns_id();
125
if (gadget_should_discard_mntns_id(mntns_id))
131
static __always_inline int trace_enter(const char *filename, int flags,
134
u64 id = bpf_get_current_pid_tgid();
139
struct start_t s = {};
141
bpf_probe_read_user_str(s.fname, sizeof(s.fname), filename);
144
if (!trace_allowed(tgid, pid, (const char *)s.fname))
151
bpf_map_update_elem(&start, &pid, &s, BPF_ANY);
156
SEC("tracepoint/syscalls/sys_enter_open")
157
int ig_open_e(struct trace_event_raw_sys_enter *ctx)
159
return trace_enter((const char *)ctx->args[0], (int)ctx->args[1],
160
(__u16)ctx->args[2]);
163
SEC("tracepoint/syscalls/sys_enter_openat")
164
int ig_openat_e(struct trace_event_raw_sys_enter *ctx)
166
return trace_enter((const char *)ctx->args[1], (int)ctx->args[2],
167
(__u16)ctx->args[3]);
170
static __always_inline int trace_exit(struct trace_event_raw_sys_exit *ctx)
174
u32 pid = bpf_get_current_pid_tgid();
175
u64 uid_gid = bpf_get_current_uid_gid();
177
size_t full_fname_len = 0;
180
s = bpf_map_lookup_elem(&start, &pid);
185
event = bpf_map_lookup_elem(&empty_event, &zero);
189
event->flags = s->flags;
190
event->mode = s->mode;
191
__builtin_memcpy(event->fname, s->fname, sizeof(s->fname));
194
if (targ_failed && ret >= 0)
198
event->pid = bpf_get_current_pid_tgid() >> 32;
199
event->uid = (u32)uid_gid;
200
event->gid = (u32)(uid_gid >> 32);
201
bpf_get_current_comm(&event->comm, sizeof(event->comm));
203
event->mntns_id = gadget_get_mntns_id();
204
event->timestamp = bpf_ktime_get_boot_ns();
207
if (ret >= 0 && get_full_path) {
208
long r = read_full_path_of_open_file_fd(
209
ret, (char *)event->full_fname,
210
sizeof(event->full_fname));
212
full_fname_len = (size_t)r;
215
event->full_fname[0] = '\0';
220
event->full_fname[0] = '\0';
225
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event,
226
sizeof(struct event) -
227
(PATH_MAX - full_fname_len));
229
bpf_map_delete_elem(&start, &pid);
233
SEC("tracepoint/syscalls/sys_exit_open")
234
int ig_open_x(struct trace_event_raw_sys_exit *ctx)
236
return trace_exit(ctx);
239
SEC("tracepoint/syscalls/sys_exit_openat")
240
int ig_openat_x(struct trace_event_raw_sys_exit *ctx)
242
return trace_exit(ctx);
245
char LICENSE[] SEC("license") = "GPL";