this repo has no description
at main 6.3 kB view raw
1#include "vmlinux.h" 2#include "uring.h" 3#include <bpf/bpf_helpers.h> 4#include <bpf/bpf_tracing.h> 5#include <bpf/bpf_core_read.h> 6 7char LICENSE[] SEC("license") = "Dual BSD/GPL"; 8 9const volatile int pid_target = 0; 10const volatile int cgroup_target = 0; 11 12struct { 13 __uint(type, BPF_MAP_TYPE_RINGBUF); 14 __uint(max_entries, 256 * 1024); 15} rb SEC(".maps"); 16 17#define FILE_NAME_LEN 256 18 19#define OPEN_KIND 0 20#define OPENAT_KIND 1 21#define OPENAT2_KIND 2 22#define URING_KIND 3 23 24// An open event 25struct open_event 26{ 27 uint32_t e_pid; 28 uint64_t e_cgid; 29 char e_comm[TASK_COMM_LEN]; 30 int e_kind; 31 int e_flags; 32 uint32_t e_mode; 33 char e_filename[FILE_NAME_LEN]; 34 int e_ret; 35}; 36 37// Temporary memory between the syscall event and the exit 38// of the event. 39struct { 40 __uint(type, BPF_MAP_TYPE_HASH); 41 __uint(max_entries, 10240); 42 __type(key, u32); // PID/User Data 43 __type(value, struct open_event); // The event 44} tmpmap SEC(".maps"); 45 46SEC("tracepoint/syscalls/sys_enter_openat") 47int tracepoint__syscalls__sys_enter_openat(struct trace_event_raw_sys_enter* ctx) 48{ 49 u64 id = bpf_get_current_pid_tgid(); 50 u32 pid = id >> 32; 51 52 if (pid_target && pid_target != pid) 53 return false; 54 55 struct open_event oet = {0}; 56 oet.e_flags = (int)ctx->args[2]; 57 oet.e_mode = (__u32)ctx->args[3]; 58 bpf_probe_read(oet.e_filename, FILE_NAME_LEN, (char *) ctx->args[1]); 59 bpf_map_update_elem(&tmpmap, &pid, &oet, BPF_NOEXIST); 60 61 return 0; 62} 63 64SEC("tracepoint/syscalls/sys_enter_openat2") 65int tracepoint__syscalls__sys_enter_openat2(struct trace_event_raw_sys_enter* ctx) 66{ 67 u64 id = bpf_get_current_pid_tgid(); 68 u32 pid = id >> 32; 69 70 if (pid_target && pid_target != pid) 71 return false; 72 73 struct open_event oet = {0}; 74 struct open_how how = {0}; 75 bpf_probe_read_user(&how, sizeof(how), (void *)ctx->args[2]); 76 oet.e_flags = (int)how.flags; 77 oet.e_mode = (__u32)how.mode; 78 bpf_probe_read(oet.e_filename, FILE_NAME_LEN, (char *) ctx->args[1]); 79 80 // Add it to the hash map 81 bpf_map_update_elem(&tmpmap, &pid, &oet, BPF_NOEXIST); 82 return 0; 83} 84 85SEC("tracepoint/syscalls/sys_enter_open") 86int tracepoint__syscalls__sys_enter_open(struct trace_event_raw_sys_enter* ctx) 87{ 88 u64 id = bpf_get_current_pid_tgid(); 89 u32 pid = id >> 32; 90 91 if (pid_target && pid_target != pid) 92 return false; 93 94 struct open_event oet = {0}; 95 oet.e_flags = (int)ctx->args[2]; 96 oet.e_mode = (__u32)ctx->args[3]; 97 bpf_probe_read(oet.e_filename, FILE_NAME_LEN, (char *) ctx->args[1]); 98 99 // Add it to the hash map 100 bpf_map_update_elem(&tmpmap, &pid, &oet, BPF_NOEXIST); 101 102 return 0; 103} 104 105 106SEC("tracepoint/syscalls/sys_exit_openat") 107int tracepoint__syscalls__sys_exit_openat(struct syscall_trace_exit* ctx) 108{ 109 struct open_event *ev; 110 u64 id = bpf_get_current_pid_tgid(); 111 u32 pid = id >> 32; 112 113 struct open_event *oet; 114 oet = bpf_ringbuf_reserve(&rb, sizeof(struct open_event), 0); 115 if (!oet) 116 return 0; 117 118 // Find our event 119 ev = bpf_map_lookup_elem(&tmpmap, &pid); 120 if (!ev) { 121 // Tidy up 122 bpf_ringbuf_discard(oet, 0); 123 bpf_map_delete_elem(&tmpmap, &pid); 124 return 0; 125 } 126 127 oet->e_ret = ctx->ret; 128 oet->e_cgid = bpf_get_current_cgroup_id(); 129 bpf_probe_read_str(&oet->e_filename, sizeof(oet->e_filename), ev->e_filename); 130 bpf_get_current_comm(oet->e_comm, TASK_COMM_LEN); 131 oet->e_flags = ev->e_flags; 132 oet->e_pid = pid; 133 oet->e_mode = ev->e_mode; 134 oet->e_kind = OPENAT_KIND; 135 136 // Tidy up 137 bpf_map_delete_elem(&tmpmap, &pid); 138 139 /* emit event */ 140 bpf_ringbuf_submit(oet, 0); 141 142 return 0; 143} 144 145SEC("tracepoint/syscalls/sys_exit_openat2") 146int tracepoint__syscalls__sys_exit_openat2(struct syscall_trace_exit* ctx) 147{ 148 struct open_event *ev; 149 u64 id = bpf_get_current_pid_tgid(); 150 u32 pid = id >> 32; 151 152 struct open_event *oet; 153 oet = bpf_ringbuf_reserve(&rb, sizeof(struct open_event), 0); 154 if (!oet) 155 return 0; 156 157 // Find our event 158 ev = bpf_map_lookup_elem(&tmpmap, &pid); 159 if (!ev) { 160 // Tidy up 161 bpf_ringbuf_discard(oet, 0); 162 bpf_map_delete_elem(&tmpmap, &pid); 163 return 0; 164 } 165 166 oet->e_ret = ctx->ret; 167 oet->e_cgid = bpf_get_current_cgroup_id(); 168 bpf_probe_read_str(&oet->e_filename, sizeof(oet->e_filename), ev->e_filename); 169 bpf_get_current_comm(oet->e_comm, TASK_COMM_LEN); 170 oet->e_flags = ev->e_flags; 171 oet->e_pid = pid; 172 oet->e_mode = ev->e_mode; 173 oet->e_kind = OPENAT2_KIND; 174 175 // Tidy up 176 bpf_map_delete_elem(&tmpmap, &pid); 177 178 /* emit event */ 179 bpf_ringbuf_submit(oet, 0); 180 181 return 0; 182} 183 184/* IO_URING is not so clean :S */ 185SEC("kprobe/io_openat2") 186int BPF_KPROBE(trace_io_uring_openat_entry, struct io_kiocb *req, int issue_flags) 187{ 188 struct io_open open; 189 int res = bpf_probe_read(&open, sizeof(open), req); 190 if (res != 0) { 191 static const char fmt[] = "openat read failed %i\n"; 192 bpf_trace_printk(fmt, sizeof(fmt), res); 193 return 0; 194 } 195 struct task_struct *task = (struct task_struct *)bpf_get_current_task_btf(); 196 char commit[TASK_COMM_LEN]; 197 198 bpf_get_current_comm(&commit, TASK_COMM_LEN); 199 200 u64 pid_tgid = bpf_get_current_pid_tgid(); 201 202 struct open_event oet = {0}; 203 struct open_how how = {0}; 204 bpf_probe_read_user(&how, sizeof(how), (void *)&open.how); 205 oet.e_flags = (int)open.how.flags; 206 oet.e_mode = (__u32)open.how.mode; 207 oet.e_filename[0] = '\0'; 208 209 bpf_map_update_elem(&tmpmap, &pid_tgid, &oet, BPF_ANY); 210 return 0; 211} 212 213// Return probe 214SEC("kretprobe/io_openat2") 215int BPF_KRETPROBE(trace_io_uring_openat_ret) 216{ 217 u64 pid_tgid = bpf_get_current_pid_tgid(); 218 219 struct open_event *ev = bpf_map_lookup_elem(&tmpmap, &pid_tgid); 220 if (!ev) { 221 static const char fmt[] = "no event\n"; 222 bpf_trace_printk(fmt, sizeof(fmt)); 223 return 0; 224 } 225 226 struct open_event *oet = bpf_ringbuf_reserve(&rb, sizeof(struct open_event), 0); 227 if (!oet) 228 return 0; 229 230 bpf_get_current_comm(oet->e_comm, TASK_COMM_LEN); 231 static const char fmt[] = "opening %s\n"; 232 bpf_trace_printk(fmt, sizeof(fmt), ev->e_filename); 233 234 oet->e_ret = 0; // TODO: PT_REGS_RC(ctx); 235 oet->e_cgid = bpf_get_current_cgroup_id(); 236 bpf_probe_read_str(&oet->e_filename, sizeof(oet->e_filename), ev->e_filename); 237 oet->e_flags = ev->e_flags; 238 oet->e_mode = ev->e_mode; 239 oet->e_kind = URING_KIND; 240 oet->e_pid = pid_tgid >> 32; 241 242 bpf_ringbuf_submit(oet, 0); 243 bpf_map_delete_elem(&tmpmap, &pid_tgid); 244 return 0; 245}