text: // SPDX-License-Identifier: GPL-2.0
  // Copyright (c) 2019 Facebook
  // Copyright (c) 2020 Netflix
  #include "vmlinux.h"
  #include <bpf/bpf_helpers.h>
  #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 pid_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
  int trace_filtered(u32 tgid, u32 pid)
  {
  	u32 uid;
  
  	/* filters */
  	if (targ_tgid && targ_tgid != tgid)
  		return 1;
  	if (targ_pid && targ_pid != pid)
  		return 1;
  	if (targ_uid) {
  		uid = bpf_get_current_uid_gid();
  		if (targ_uid != uid) {
  			return 1;
  		}
  	}
  	return 0;
  }
  
  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_filtered(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_filtered(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_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";
  