Skip to content

Commit

Permalink
fs_watcher_new
Browse files Browse the repository at this point in the history
Signed-off-by: shangfan <45649554+sf1999817@users.noreply.github.com>
  • Loading branch information
sf1999817 committed Jul 9, 2024
1 parent 8acf979 commit 25d6be4
Show file tree
Hide file tree
Showing 6 changed files with 582 additions and 0 deletions.
77 changes: 77 additions & 0 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/bpf/open.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#define BPF_NO_GLOBAL_DATA
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

#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, 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("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;

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;
}

char LICENSE[] SEC("license") = "GPL";
99 changes: 99 additions & 0 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/bpf/read.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "read.h"
#define MAX_FILENAME_LEN 256

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

// 手动定义文件类型宏
#define S_IFMT 0170000 // 文件类型掩码
#define S_IFREG 0100000 // 普通文件
#define S_IFCHR 0020000 // 字符设备
#define S_IFDIR 0040000 // 目录
#define S_IFLNK 0120000 // 符号链接
#define S_IFBLK 0060000 // 块设备
#define S_IFIFO 0010000 // FIFO(命名管道)
#define S_IFSOCK 0140000 // 套接字

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, MAX_FILENAME_LEN);
} 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 *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 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");
}
// 判断文件类型,并过滤掉设备文件
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)
return 0;
e->pid = pid;
e->duration_ns = ts;
/* successfully submit it to user-space for post-processing */
bpf_ringbuf_submit(e, 0);
return 0;
}
62 changes: 62 additions & 0 deletions eBPF_Supermarket/Filesystem_Subsystem/fs_watcher/bpf/write.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "write.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";
#define PATH_MAX 256
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, pid_t);
__type(value, int);
} data SEC(".maps");

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


SEC("kprobe/vfs_write")
int kprobe_vfs_write(struct pt_regs *ctx)
{
pid_t pid;
struct fs_t *e;
unsigned long inode_number;//定义用于存储inode号码的变量

//探测的是第一个参数,文件指针,读取inode_number
struct file *filp = (struct file *)PT_REGS_PARM1(ctx);  
struct dentry *dentry = BPF_CORE_READ(filp,f_path.dentry);
if(!dentry){
bpf_printk("Failed to read dentry\n");
return 0;
}
struct inode *inode = BPF_CORE_READ(dentry,d_inode);
if(!inode){
bpf_printk("Failed to read inode\n");
return 0;
}
int ret = bpf_probe_read_kernel(&inode_number,sizeof(inode_number),&inode->i_ino);

//探测的是第三个参数,要写入的字节数
size_t count = (size_t)PT_REGS_PARM3(ctx);

//这是vfs_write的返回值,它是一个实际写入的字节数
size_t real_count = PT_REGS_RC(ctx);

pid = bpf_get_current_pid_tgid() >> 32;
e = bpf_ringbuf_reserve(&rb,sizeof(*e),0);
if(!e)
return 0;

e->pid = pid;
e->real_count = real_count;
e->count = count;
e->inode_number = inode_number;

//这里将获取到的文件指针不为空时
bpf_ringbuf_submit(e, 0);
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
#include "fs_watcher.h"
Loading

0 comments on commit 25d6be4

Please sign in to comment.