Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs_watcher:添加-n选项进行filename过滤 && 添加logo图案 && 将read程序重新修改输出 #961

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 16 additions & 22 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/open.bpf.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
#include <vmlinux.h>
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "fs_watcher.h"

char LICENSE[] SEC("license") = "GPL";

#define O_CREAT 0x0200 // 手动定义 O_CREAT 标志的常量值
#define O_WRONLY 01 /* open for writing only */

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
Expand All @@ -30,32 +27,31 @@ int do_syscall_trace(struct trace_event_raw_sys_enter *ctx)
e.dfd = ctx->args[0];// 目录文件描述符
bpf_probe_read_user_str(e.filename, sizeof(e.filename), (const char *)ctx->args[1]); // 文件路径
e.flags = ctx->args[2]; // 打开标志

// 如果包含 O_CREAT 标志,则标记为文件创建
if (e.flags & O_CREAT || (e.flags & O_WRONLY) ) {
e.is_created = true;
} else {
e.is_created = false;
}

bpf_map_update_elem(&data,&pid,&e,BPF_ANY);
return 0;
}

// 跟踪文件描述符分配过程
SEC("kprobe/get_unused_fd_flags")
int kprobe_get_unused_fd_flags(struct pt_regs *ctx){
//跟踪文件描述符分配过程
SEC("kretprobe/get_unused_fd_flags")
int kretprobe_get_unused_fd_flags(struct pt_regs *ctx){
pid_t pid = bpf_get_current_pid_tgid() >> 32;
struct event_open *e = bpf_map_lookup_elem(&data,&pid);
if(!e){
bpf_printk("get_unused_fd_flags is failed to found fd\n");
return 0;
}
//获取分配的文件描述符
int fd = PT_REGS_RC(ctx);

//获取分配的文件描述符
e->fd = PT_REGS_RC(ctx);

bpf_map_update_elem(&data,&pid,e,BPF_ANY);
if (fd <= 0) {
bpf_printk("get_unused_fd_flags: syscall failed with error %d\n", fd);
return 0;
} else {
bpf_printk("get_unused_fd_flags: allocated fd %d\n", fd);
e->fd = fd;
bpf_map_update_elem(&data, &pid, e, BPF_ANY);
}
return 0;
}

Expand All @@ -72,7 +68,7 @@ int do_syscall_exit(struct trace_event_raw_sys_exit *ctx)

e->ret = ctx->ret;

// 分配 ringbuf 空间
// 分配 ringbuf 空间
struct event_open *new_e = bpf_ringbuf_reserve(&rb, sizeof(*new_e), 0);
if (!new_e) {
return 0; // 如果分配失败,提前返回
Expand All @@ -82,8 +78,7 @@ int do_syscall_exit(struct trace_event_raw_sys_exit *ctx)
new_e->dfd = e->dfd;
new_e->flags = e->flags;
new_e->fd = e->fd;
new_e->ret =e->ret;
new_e->is_created = e->is_created;
new_e->ret = e->ret;
new_e->pid = e->pid;

// 手动读取文件路径,确保不超过最大长度,并添加 '\0' 结束符
Expand All @@ -98,7 +93,6 @@ int do_syscall_exit(struct trace_event_raw_sys_exit *ctx)
// 确保字符串以 '\0' 结束
new_e->filename[filename_len] = '\0';
bpf_printk("Opening file: %s, pid: %d, flags: %d\n", new_e->filename, pid, e->flags);

bpf_ringbuf_submit(new_e, 0);
return 0;
}
94 changes: 39 additions & 55 deletions MagicEyes/src/backend/fs/fs_watcher/bpf/read.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "fs_watcher.h"
#define MAX_FILENAME_LEN 256

char LICENSE[] SEC("license") = "Dual BSD/GPL";

Expand All @@ -21,79 +20,64 @@ struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, MAX_FILENAME_LEN);
__type(value, struct event_read);
} data SEC(".maps");

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

const volatile unsigned long long min_duration_ns = 0;

SEC("kprobe/vfs_read")
int kprobe_enter_read(struct pt_regs *ctx)
{
struct file *filp = (struct file *)PT_REGS_PARM1(ctx);  
pid_t pid;
struct event_read *e;
u64 ts;
char buf[256];
pid = bpf_get_current_pid_tgid() >> 32;
ts = bpf_ktime_get_ns()/1000;
int count_size = PT_REGS_RC(ctx);
if (min_duration_ns)
return 0;

struct event_read e = {};
struct file *filp = (struct file *)PT_REGS_PARM1(ctx);
pid_t pid = bpf_get_current_pid_tgid() >> 32;
e.pid = pid; //获取进程pid
size_t count = (size_t)PT_REGS_PARM3(ctx); // 获取请求读取的字节数

//获取文件路径结构体
struct dentry *dentry = BPF_CORE_READ(filp, f_path.dentry);
if(!dentry){
bpf_printk("Failed to read dentry\n");
return 0;
}
struct qstr d_name = BPF_CORE_READ(dentry,d_name);

//读文件名称到缓冲区
int ret = bpf_probe_read_kernel(buf, sizeof(buf), d_name.name);
if(ret != 0){
bpf_printk("failed to read file name\n");
}
bpf_probe_read_str(e.filename, sizeof(e.filename), d_name.name); // 读取文件名
// 判断文件类型,并过滤掉设备文件
unsigned short file_type = BPF_CORE_READ(dentry, d_inode, i_mode) & S_IFMT;
bpf_map_update_elem(&data, &pid, &buf, BPF_ANY);
switch (file_type) {
case S_IFREG:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFCHR:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFDIR:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFLNK:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFBLK:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFIFO:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
case S_IFSOCK:
bpf_printk("Regular file name: %s,count_size :%d", buf,count_size);
break;
default:
bpf_printk("other!!!");
break;
}
/* reserve sample from BPF ringbuf */
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
if (!e)
e.file_type = file_type;
bpf_map_update_elem(&data,&pid,&e,BPF_ANY);
return 0;
}

SEC("kretprobe/vfs_read")
int kretprobe_exit_read(struct pt_regs *ctx)
{
pid_t pid = bpf_get_current_pid_tgid() >> 32;
ssize_t real_count = PT_REGS_RC(ctx); // 获取实际返回的字节数
struct event_read *e = bpf_map_lookup_elem(&data, &pid);
if(!e){
bpf_printk("Failed to found read event\n");
return 0;
e->pid = pid;
e->duration_ns = ts;
/* successfully submit it to user-space for post-processing */
bpf_ringbuf_submit(e, 0);
}
e->count_size = real_count;

// 使用 ring buffer 向用户态传递数据
struct event_read *e_ring = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
if (!e_ring) {
return 0; // 如果 ring buffer 没有足够空间,直接返回
}

// 将数据填充到 ring buffer 中
*e_ring = *e;

// 提交数据到 ring buffer
bpf_ringbuf_submit(e_ring, 0);

// 删除哈希表中的该事件数据,避免泄露
bpf_map_delete_elem(&data, &pid);

return 0;
}
27 changes: 11 additions & 16 deletions MagicEyes/src/backend/fs/fs_watcher/include/fs_watcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
#define TASK_COMM_LEN 16

struct event_open {
pid_t pid;
int dfd;
char filename[path_size];
int flags;
int fd; // 文件描述符
int ret; // 系统调用返回值
bool is_created; // 标记文件是否创建
pid_t pid; // 进程 ID
int dfd; // 目录文件描述符
char filename[256]; // 文件路径
int flags; // 打开标志
int fd; // 文件描述符
int ret; // 系统调用返回值
};

/*read*/

struct event_read {
int pid;
unsigned long long duration_ns;
int pid;
char filename[256]; // 文件名
int count_size; // 读取的字节数
unsigned short file_type; // 文件类型
};

/*write*/
Expand Down Expand Up @@ -64,9 +64,4 @@ struct event_CacheTrack{
long long time_complete; // 写回开始时间
};

/*send pid to ebpf*/
struct dist_args {
pid_t pid;
};
#endif /* __MEM_WATCHER_H */

#endif /* __FS_WATCHER_H */
Loading