forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libbpf-tools: add CO-RE opensnoop (iovisor#2778)
* libbpf-tools: add CO-RE opensnoop * libbpf-tools/opensnoop: feedback
- Loading branch information
1 parent
c9cfb52
commit 5e123df
Showing
4 changed files
with
471 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// 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 | ||
|
||
#define BPF_F_INDEX_MASK 0xffffffffULL | ||
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK | ||
|
||
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"; |
Oops, something went wrong.