Skip to content

User-specified file monitoring with continuous file addition and tracepoints added. #1

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

Open
wants to merge 2 commits into
base: main
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
4 changes: 4 additions & 0 deletions allowed_files.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
"/home/yashas/Desktop//h/hi.txt",
"/home/yashas/Desktop/h/a3.txt"
]
149 changes: 148 additions & 1 deletion bpf/file_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
#include <sys/syscall.h>

//#include <sys/syscall.h>

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

Expand All @@ -27,6 +28,57 @@ struct unlinkat_ctx {
int flag;
};

// Matches /sys/kernel/debug/tracing/events/syscalls/sys_enter_write/format
struct write_ctx {
unsigned long pad;
__u64 __unused_syscall_header;
int syscall_nr;
int fd;
const char *buf;
__u64 count;
};

struct renameat2_ctx {
unsigned long pad;
__u64 __unused_syscall_header;
int syscall_nr;
int olddfd;
const char *oldname;
int newdfd;
const char *newname;
unsigned int flags;
};


struct fchmodat_ctx {
unsigned long long __pad;
__u64 __unused_syscall_header;
int syscall_nr;
int dfd;
const char *filename;
__u16 mode;
};

struct fchownat_ctx {
unsigned long pad;
__u64 __unused_syscall_header;
int syscall_nr;
int dfd;
const char *filename;
__u32 user; // instead of uid_t
__u32 group; // instead of gid_t
int flag;
};


// Defined according to /sys/kernel/debug/tracing/events/syscalls/sys_exit_close/format
struct close_ctx {
unsigned long pad;
__u64 __unused_syscall_header;
int syscall_nr;
int fd;
};

struct event {
__u32 pid;
char command[16];
Expand All @@ -41,6 +93,13 @@ struct {
__uint(max_entries, 1024);
} events SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, int);
__type(value, char[256]);
} fd_to_filename SEC(".maps");

SEC("tracepoint/syscalls/sys_enter_openat")
int trace_openat(struct openat_ctx *ctx) {
struct event event = {};
Expand All @@ -53,6 +112,9 @@ int trace_openat(struct openat_ctx *ctx) {

__builtin_memcpy(event.op, "OPEN", 5);

int fd = ctx->dfd;
bpf_map_update_elem(&fd_to_filename, &fd, event.filename, BPF_ANY);

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event,
sizeof(event));
return 0;
Expand All @@ -69,8 +131,93 @@ int trace_unlinkat(struct unlinkat_ctx *ctx) {
bpf_probe_read_user_str(event.filename, sizeof(event.filename), pathname);

__builtin_memcpy(event.op, "DELETE", 7);

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event,
sizeof(event));
return 0;
}

SEC("tracepoint/syscalls/sys_enter_write")
int trace_write(struct write_ctx *ctx) {
struct event event = {};

event.pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event.command, sizeof(event.command));

// Write doesn't give filename, just file descriptor
// We'll format a placeholder string for the fd
int fd = ctx->fd;
__builtin_memcpy(event.op, "WRITE", 6);

// Turn fd into a readable string like "fd=3"
// Crude formatting — for robust solution use bpf_snprintf (in newer kernels)
// Resolve filename from FD-to-Filename map
char *filename = bpf_map_lookup_elem(&fd_to_filename, &fd);
if (filename) {
bpf_probe_read_kernel_str(event.filename, sizeof(event.filename), filename);
} else {
__builtin_memset(event.filename, 0, sizeof(event.filename)); // Clear filename if not found
}
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event,
sizeof(event));
return 0;

}

SEC("tracepoint/syscalls/sys_enter_renameat2")
int trace_renameat2(struct renameat2_ctx *ctx) {
struct event event = {};

// Common event fields
event.pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event.command, sizeof(event.command));

// Send "RENAME" event for oldname
bpf_probe_read_user_str(event.filename, sizeof(event.filename), ctx->oldname);
__builtin_memcpy(event.op, "RENAME", 7);
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));

// Send "RENAMED" event for newname
bpf_probe_read_user_str(event.filename, sizeof(event.filename), ctx->newname);
__builtin_memcpy(event.op, "RENAMED", 8);
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));

return 0;
}

SEC("tracepoint/syscalls/sys_enter_fchmodat")
int trace_fchmodat(struct fchmodat_ctx *ctx) {
struct event event = {};

event.pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event.command, sizeof(event.command));
bpf_probe_read_user_str(event.filename, sizeof(event.filename), ctx->filename);
__builtin_memcpy(event.op, "CHMOD", 6);

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
return 0;
}

SEC("tracepoint/syscalls/sys_enter_fchownat")
int trace_fchownat(struct fchownat_ctx *ctx) {
struct event event = {};

event.pid = bpf_get_current_pid_tgid() >> 32;
bpf_get_current_comm(&event.command, sizeof(event.command));

bpf_probe_read_user_str(event.filename, sizeof(event.filename), ctx->filename);
__builtin_memcpy(event.op, "CHOWN", 6);

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
return 0;
}

SEC("tracepoint/syscalls/sys_exit_close")
int trace_close(struct close_ctx *ctx) {
int fd = ctx->fd;

// Remove the file descriptor from the fd_to_filename map
bpf_map_delete_elem(&fd_to_filename, &fd);

return 0;
}
Loading