// SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019 Facebook // Copyright (c) 2020 Netflix #include #include #include "opensnoop.h" #define TASK_RUNNING 0 const volatile __u64 min_us = 0; const volatile pid_t targ_pid = 0; const volatile pid_t targ_tgid = 0; const volatile uid_t targ_uid = 0; const volatile bool targ_failed = false; struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 10240); __type(key, u32); __type(value, struct args_t); } start SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); __uint(key_size, sizeof(u32)); __uint(value_size, sizeof(u32)); } events SEC(".maps"); static __always_inline bool valid_uid(uid_t uid) { return uid != INVALID_UID; } static __always_inline bool trace_allowed(u32 tgid, u32 pid) { u32 uid; /* filters */ if (targ_tgid && targ_tgid != tgid) return false; if (targ_pid && targ_pid != pid) return false; if (valid_uid(targ_uid)) { uid = (u32)bpf_get_current_uid_gid(); if (targ_uid != uid) { return false; } } return true; } SEC("tracepoint/syscalls/sys_enter_open") int tracepoint__syscalls__sys_enter_open(struct trace_event_raw_sys_enter* ctx) { u64 id = bpf_get_current_pid_tgid(); /* use kernel terminology here for tgid/pid: */ u32 tgid = id >> 32; u32 pid = id; /* store arg info for later lookup */ if (trace_allowed(tgid, pid)) { struct args_t args = {}; args.fname = (const char *)ctx->args[0]; args.flags = (int)ctx->args[1]; bpf_map_update_elem(&start, &pid, &args, 0); } return 0; } SEC("tracepoint/syscalls/sys_enter_openat") int tracepoint__syscalls__sys_enter_openat(struct trace_event_raw_sys_enter* ctx) { u64 id = bpf_get_current_pid_tgid(); /* use kernel terminology here for tgid/pid: */ u32 tgid = id >> 32; u32 pid = id; /* store arg info for later lookup */ if (trace_allowed(tgid, pid)) { struct args_t args = {}; args.fname = (const char *)ctx->args[1]; args.flags = (int)ctx->args[2]; bpf_map_update_elem(&start, &pid, &args, 0); } return 0; } static __always_inline int trace_exit(struct trace_event_raw_sys_exit* ctx) { struct event event = {}; struct args_t *ap; int ret; u32 pid = bpf_get_current_pid_tgid(); ap = bpf_map_lookup_elem(&start, &pid); if (!ap) return 0; /* missed entry */ ret = ctx->ret; if (targ_failed && ret >= 0) goto cleanup; /* want failed only */ /* event data */ event.pid = bpf_get_current_pid_tgid() >> 32; event.uid = bpf_get_current_uid_gid(); bpf_get_current_comm(&event.comm, sizeof(event.comm)); bpf_probe_read_user_str(&event.fname, sizeof(event.fname), ap->fname); event.flags = ap->flags; event.ret = ret; /* emit event */ bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event)); cleanup: bpf_map_delete_elem(&start, &pid); return 0; } SEC("tracepoint/syscalls/sys_exit_open") int tracepoint__syscalls__sys_exit_open(struct trace_event_raw_sys_exit* ctx) { return trace_exit(ctx); } SEC("tracepoint/syscalls/sys_exit_openat") int tracepoint__syscalls__sys_exit_openat(struct trace_event_raw_sys_exit* ctx) { return trace_exit(ctx); } char LICENSE[] SEC("license") = "GPL";