Skip to content

Commit

Permalink
Merge pull request #826 from sf1999817/develop
Browse files Browse the repository at this point in the history
fs_watcher:给open系统调用添加提取路径参数信息还有文件描述符
  • Loading branch information
13186379707 committed Jun 18, 2024
2 parents 08b982c + 4c17797 commit d7c342b
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 96 deletions.
108 changes: 61 additions & 47 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.bpf.c
Original file line number Diff line number Diff line change
@@ -1,63 +1,77 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h> //包含了BPF 辅助函数
#define BPF_NO_GLOBAL_DATA
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "open.h"
#include <bpf/bpf_core_read.h>

char LICENSE[] SEC("license") = "Dual BSD/GPL";
#define TASK_COMM_LEN 100
#define path_size 256

// 定义哈希映射
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, u64);
} fdtmp SEC(".maps");
__type(value, char[TASK_COMM_LEN]);
} data SEC(".maps");

struct event {
int pid_;
char path_name_[path_size];
int n_;
char comm[TASK_COMM_LEN];
};

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

SEC("kprobe/do_sys_openat2")
int BPF_KPROBE(do_sys_openat2)
{
struct fs_t fs;
pid_t pid;

//pid
pid = bpf_get_current_pid_tgid() >> 32;
fs.pid = pid;

//uid
fs.uid = bpf_get_current_uid_gid();

//fd,file descriptor
int fd = PT_REGS_RC(ctx);
if (fd >= 0)
fs.fd = fd;
else
fs.fd= -1;

//time
unsigned long long ts = bpf_ktime_get_ns();
fs.ts = ts;
bpf_map_update_elem(&fdtmp, &pid, &ts, BPF_ANY);

//从环形缓冲区(ring buffer)中分配一块内存来存储一个名为 struct fs_t 类型的数据,并将该内存块的指针赋值给指针变量 e
struct fs_t *e;
} rb SEC(".maps"); // 环形缓冲区


SEC("tracepoint/syscalls/sys_enter_openat")
int do_syscall_trace(struct trace_event_raw_sys_enter *ctx)
{
struct event *e;
char comm[TASK_COMM_LEN];
bpf_get_current_comm(&comm,sizeof(comm));
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
if (!e) return 0;

//给变量e赋值
e->pid = fs.pid;
e->uid = fs.uid;
e->fd = fs.fd;
e->ts = fs.ts;
bpf_get_current_comm(e->comm, sizeof(e->comm));

// 成功地将其提交到用户空间进行后期处理
if (!e)
return 0;

char filename[path_size];
struct task_struct *task = (struct task_struct *)bpf_get_current_task(),
*real_parent;
if (task == NULL) {
bpf_printk("task\n");
bpf_ringbuf_discard(e, 0);
return 0;
}
int pid = bpf_get_current_pid_tgid() >> 32, tgid;

bpf_map_update_elem(&data, &pid, &comm, BPF_ANY);

int ppid = BPF_CORE_READ(task, real_parent, tgid);

bpf_probe_read_str(e->path_name_, sizeof(e->path_name_),
(void *)(ctx->args[1]));

bpf_printk("path name: %s,pid:%d,ppid:%d\n", e->path_name_, pid, ppid);

struct fdtable *fdt = BPF_CORE_READ(task, files, fdt);
if (fdt == NULL) {
bpf_printk("fdt\n");
bpf_ringbuf_discard(e, 0);
return 0;
}

unsigned int i = 0, count = 0, n = BPF_CORE_READ(fdt, max_fds);
bpf_printk("n:%d\n", n);

e->n_ = n;
e->pid_ = pid;

bpf_ringbuf_submit(e, 0);

return 0;
return 0;
}

char LICENSE[] SEC("license") = "GPL";
127 changes: 84 additions & 43 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
/* Copyright (c) 2020 Facebook */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include <signal.h>
#include "open.skel.h" //包含了 BPF 字节码和相关的管理函数
#include "open.h"
#include <bpf/bpf.h>
#include <unistd.h>
#include <stdlib.h>
#include "open.skel.h"
#include <inttypes.h>
#include <linux/fs.h>
#include <errno.h>

#define path_size 256
#define TASK_COMM_LEN 16

struct event {
int pid_;
char path_name_[path_size];
int n_;
char comm[TASK_COMM_LEN];
};

#define warn(...) fprintf(stderr, __VA_ARGS__)

static int libbpf_print_fn(enum libbpf_print_level level, const char *format,
va_list args)
{
return vfprintf(stderr, format, args);
}

static volatile bool exiting = false;

Expand All @@ -13,18 +41,34 @@ static void sig_handler(int sig)
exiting = true;
}

static int handle_event(void *ctx, void *data,unsigned long data_sz)
static int handle(void *ctx, void *data, size_t data_sz)
{
const struct fs_t *e = data;
printf("pid:%d uid:%llu time:%llu fd:%d comm:%s\n",e->pid,e->uid,e->ts,e->fd,e->comm);

return 0;
}

struct event *e = (struct event *)data;
char *filename = strrchr(e->path_name_, '/');
++filename;

static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
char fd_path[path_size];
char actual_path[path_size];
char comm[TASK_COMM_LEN];
int i = 0;
int map_fd = *(int *)ctx;//传递map得文件描述符

for (; i < e->n_; ++i) {
snprintf(fd_path, sizeof(fd_path), "/proc/%d/fd/%d", e->pid_,i);
ssize_t len = readlink(fd_path, actual_path, sizeof(actual_path) - 1);
if (len != -1) {
actual_path[len] = '\0';
int result = strcmp(e->path_name_, actual_path);
if (result == 0) {
if(bpf_map_lookup_elem(map_fd,&e->pid_,&comm)==0){
printf("get , filename:%s , fd:%d , pid:%d ,comm:%s\n", e->path_name_, i,e->pid_,comm);
}else{
fprintf(stderr, "Failed to lookup value for key %d\n", e->pid_);
}
}
}
}
return 0;
}

int main(int argc, char **argv)
Expand All @@ -33,50 +77,51 @@ int main(int argc, char **argv)
struct open_bpf *skel;
int err;

libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
/* 设置libbpf错误和调试信息回调 */
/* Set up libbpf errors and debug info callback */
libbpf_set_print(libbpf_print_fn);

/* 更干净地处理Ctrl-C
SIGINT:由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGTERM:请求中止进程,kill命令发送
*/
signal(SIGINT, sig_handler); //signal设置某一信号的对应动作
/* Cleaner handling of Ctrl-C */
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);

/* 打开BPF应用程序 */
/* Load and verify BPF application */
skel = open_bpf__open();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
fprintf(stderr, "Failed to open and load BPF skeleton\n");
return 1;
}
/* 加载并验证BPF程序 */

/* Load & verify BPF programs */
err = open_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup;
}

/* 附加跟踪点处理程序 */
err = open_bpf__attach(skel);
if (err) {

int attach = open_bpf__attach(skel);
if (attach) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
err = -1;
goto cleanup;
}

/* 设置环形缓冲区轮询 */
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); //ring_buffer__new() API,允许在不使用额外选项数据结构下指定回调

int map_fd = bpf_map__fd(skel->maps.data);
if(!map_fd){
fprintf(stderr, "Failed to find BPF map\n");
return -1;
}

rb = ring_buffer__new(
bpf_map__fd(skel->maps.rb), handle, &map_fd, NULL); // 创建一个环形缓冲区,并设置好缓冲区的回调函数
if (!rb) {
err = -1;
fprintf(stderr, "Failed to create ring buffer\n");
goto cleanup;
}

/* 处理事件 */

while (!exiting) {
err = ring_buffer__poll(rb, 100 /* timeout, ms */); //ring_buffer__poll(),轮询打开ringbuf缓冲区。如果有事件,handle_event函数会执行
/* Ctrl-C will cause -EINTR */
err = ring_buffer__poll(rb, 100);

if (err == -EINTR) {
err = 0;
break;
Expand All @@ -85,15 +130,11 @@ int main(int argc, char **argv)
printf("Error polling perf buffer: %d\n", err);
break;
}

//exiting = true; //使用该程序时,将该行代码注释掉

}

/* 卸载BPF程序 */
cleanup:
/* Clean up */
ring_buffer__free(rb);
open_bpf__destroy(skel);

return err < 0 ? -err : 0;
}
}
11 changes: 5 additions & 6 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/open.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
#define TASK_COMM_LEN 16
#endif

struct fs_t {
int pid;
unsigned long long uid;
int fd;
unsigned long long ts;
char comm[TASK_COMM_LEN];
struct event {
int pid_;
char path_name_[path_size];
int n_;
char comm[TASK_COMM_LEN];
};

#endif /* __OPEN_H */

0 comments on commit d7c342b

Please sign in to comment.