Skip to content

Commit 4aaa67f

Browse files
technoBlogger-2001siddh34
authored andcommitted
Merge pull request #6 from SentinalFS/fix/renameAndDelete
Fix/rename and delete
2 parents 075f3c5 + 77cc516 commit 4aaa67f

12 files changed

Lines changed: 390 additions & 102 deletions

File tree

.github/workflows/releases.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
tag_name: v${{ env.version }}
6262
name: Release v${{ env.version }}
6363
files: build/monitor.bpf.o
64-
# generate_release_notes: true
64+
generate_release_notes: true
6565
env:
6666
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6767

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
"cstdio": "c",
1919
"*.inc": "c",
2020
"bpf_core_read.h": "c",
21-
"data_types.h": "c"
21+
"data_types.h": "c",
22+
"chrono": "c",
23+
"text_encoding": "c",
24+
"typeinfo": "c"
2225
}
2326
}

CHANGELOG.json

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
[ {
2-
"version": "0.2.0",
3-
"changes": [
4-
"Implimented ring buffer for file events"
5-
]
6-
},
7-
{
8-
"version": "0.1.2",
9-
"changes": [
10-
"Fix release extras"
11-
]
12-
},
1+
[
132
{
14-
"version": "0.1.1",
3+
"version": "0.3.0",
154
"changes": [
16-
"Added support for monitoring file deletions",
17-
"Improved performance for large directories",
18-
"Fixed a bug where some file events were not captured"
5+
"Fix rename and delete events",
6+
"Added cgroup support for file events"
197
]
208
},
21-
{
22-
"version": "0.1.0",
23-
"changes": [
24-
"A local file monitoring tool early release",
25-
"Can monitor read, write, rename, create"
26-
]
27-
}
28-
]
9+
{
10+
"version": "0.2.0",
11+
"changes": ["Implimented ring buffer for file events"]
12+
},
13+
{
14+
"version": "0.1.2",
15+
"changes": ["Fix release extras"]
16+
},
17+
{
18+
"version": "0.1.1",
19+
"changes": [
20+
"Added support for monitoring file deletions",
21+
"Improved performance for large directories",
22+
"Fixed a bug where some file events were not captured"
23+
]
24+
},
25+
{
26+
"version": "0.1.0",
27+
"changes": [
28+
"A local file monitoring tool early release",
29+
"Can monitor read, write, rename, create"
30+
]
31+
}
32+
]

README.md

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,113 @@
1-
# Local_file_monitor
1+
# file monitor
22

3-
It monitors local files
3+
It monitors files
44

5+
## Dir structure
6+
7+
```
8+
.
9+
├── CHANGELOG.json
10+
├── CMakeLists.txt
11+
├── common.h
12+
├── data_types.h
13+
├── headers.h
14+
├── helpers
15+
│ ├── delete.h
16+
│ ├── read_write.h
17+
│ └── rename.h
18+
├── monitor.c
19+
├── README.md
20+
├── VERSION.txt
21+
└── vmlinux.h
22+
```
23+
24+
## BPF traces
25+
26+
### VFS Read
27+
28+
```sh
29+
sudo bpftrace -e 'kprobe:vfs_read {
30+
$file = (struct file *)arg0;
31+
$dentry = $file->f_path.dentry;
32+
33+
if ($dentry != 0) {
34+
printf("READ - File: %s, Size: %d bytes, PID: %d, Comm: %s\n",
35+
str($dentry->d_name.name),
36+
arg2, // count/size parameter
37+
pid,
38+
comm);
39+
40+
$parent = $dentry->d_parent;
41+
if ($parent != 0) {
42+
printf(" Parent dir: %s\n", str($parent->d_name.name));
43+
}
44+
}
45+
}'
46+
```
47+
48+
### VFS Write
49+
50+
```sh
51+
sudo bpftrace -e 'kprobe:vfs_write {
52+
$file = (struct file *)arg0;
53+
$dentry = $file->f_path.dentry;
54+
55+
if ($dentry != 0) {
56+
printf("WRITE - File: %s, Size: %d bytes, PID: %d, Comm: %s\n",
57+
str($dentry->d_name.name),
58+
arg2, // count/size parameter
59+
pid,
60+
comm);
61+
62+
$parent = $dentry->d_parent;
63+
if ($parent != 0) {
64+
printf(" Parent dir: %s\n", str($parent->d_name.name));
65+
}
66+
}
67+
}'
68+
```
69+
70+
### VFS Rename
71+
72+
```sh
73+
sudo bpftrace -e 'kprobe:vfs_rename {
74+
$old_dentry = (struct dentry *)arg1;
75+
$new_dentry = (struct dentry *)arg3;
76+
77+
if ($old_dentry != 0 && $new_dentry != 0) {
78+
printf("RENAME - From: %s, To: %s, PID: %d, Comm: %s\n",
79+
str($old_dentry->d_name.name),
80+
str($new_dentry->d_name.name),
81+
pid,
82+
comm);
83+
84+
$old_parent = $old_dentry->d_parent;
85+
$new_parent = $new_dentry->d_parent;
86+
87+
if ($old_parent != 0) {
88+
printf(" Source dir: %s\n", str($old_parent->d_name.name));
89+
}
90+
91+
if ($new_parent != 0) {
92+
printf(" Target dir: %s\n", str($new_parent->d_name.name));
93+
}
94+
}
95+
}'
96+
```
97+
98+
### VFS Unlink
99+
100+
```sh
101+
sudo bpftrace -e 'kprobe:vfs_unlink {
102+
$dentry = (struct dentry *)arg2;
103+
printf("dentry ptr: %p, d_name.len: %d, d_name.name_ptr: %s\n",
104+
$dentry, $dentry->d_name.len, str($dentry->d_name.name));
105+
106+
$parent = $dentry->d_parent;
107+
if ($parent != 0) {
108+
printf("Parent name: %s\n", str($parent->d_name.name));
109+
} else {
110+
printf("Parent: NULL\n");
111+
}
112+
}'
113+
```

VERSION.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.0
1+
0.3.0

common.h

Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,11 @@
1+
#ifndef COMMON_H
2+
#define COMMON_H
3+
14
#include "headers.h"
25
#include "data_types.h"
6+
#include "helpers/read_write.h"
7+
#include "helpers/rename.h"
8+
#include "helpers/delete.h"
9+
// Common includes and definitions can stay here
310

4-
static __always_inline int trace_file_operation(struct pt_regs *ctx, struct file *file, const char *operation)
5-
{
6-
if (!file)
7-
return 0;
8-
9-
struct data_t *data = bpf_ringbuf_reserve(&events, sizeof(struct data_t), 0);
10-
if (!data) {
11-
return 0;
12-
}
13-
__builtin_memset(data, 0, sizeof(*data));
14-
15-
16-
struct dentry *de = NULL;
17-
bpf_core_read(&de, sizeof(de), &file->f_path.dentry);
18-
if (!de) {
19-
bpf_ringbuf_discard(data, 0);
20-
return 0;
21-
}
22-
23-
struct qstr d_name = {};
24-
bpf_core_read(&d_name, sizeof(d_name), &de->d_name);
25-
if (d_name.len == 0) {
26-
bpf_ringbuf_discard(data, 0);
27-
return 0;
28-
}
29-
30-
char fname[128] = {};
31-
bpf_core_read_str(fname, sizeof(fname), d_name.name);
32-
33-
data->pid = bpf_get_current_pid_tgid() >> 32;
34-
data->uid = bpf_get_current_uid_gid();
35-
data->timestamp = bpf_ktime_get_ns();
36-
37-
__builtin_memcpy(data->filename, fname, sizeof(data->filename));
38-
__builtin_memcpy(data->otype, operation, sizeof(data->otype));
39-
bpf_get_current_comm(&data->comm, sizeof(data->comm));
40-
41-
struct inode *inode = NULL;
42-
bpf_core_read(&inode, sizeof(inode), &file->f_inode);
43-
if (!inode) {
44-
bpf_ringbuf_discard(data, 0);
45-
return 0;
46-
}
47-
48-
u32 inode_num = 0;
49-
bpf_core_read(&inode_num, sizeof(inode_num), &inode->i_ino);
50-
51-
struct inode_key key = {.inode = inode_num};
52-
53-
bpf_trace_printk("LOG: filename=%s otype=%s comm=%s\n", sizeof("LOG: filename=%s otype=%s comm=%s\n"), data->filename, data->otype, data->comm);
54-
bpf_trace_printk("LOG: inode=%u\n", sizeof("LOG: inode=%u\n"), inode_num);
55-
56-
u32 *monitored = bpf_map_lookup_elem(&monitored_inodes, &key);
57-
if (!monitored) {
58-
bpf_ringbuf_discard(data, 0);
59-
return 0;
60-
}
61-
62-
bpf_ringbuf_submit(data, 0);
63-
64-
return 0;
65-
}
11+
#endif /* COMMON_H */

data_types.h

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1+
#ifndef DATA_TYPES_H
2+
#define DATA_TYPES_H
3+
14
#include "headers.h"
25

36
struct {
47
__uint(type, BPF_MAP_TYPE_RINGBUF);
5-
__uint(max_entries, 256 * 1024);
8+
__uint(max_entries, 512 * 1024);
69
} events SEC(".maps");
710

11+
struct {
12+
__uint(type, BPF_MAP_TYPE_RINGBUF);
13+
__uint(max_entries, 256 * 1024);
14+
} rename_events SEC(".maps");
15+
816
struct
917
{
1018
__uint(type, BPF_MAP_TYPE_HASH);
@@ -23,8 +31,23 @@ struct data_t
2331
{
2432
u32 pid;
2533
u32 uid;
26-
char filename[128];
27-
char comm[16];
34+
char filename[FILE_NAME_SIZE];
35+
char comm[COMM_SIZE];
36+
u64 timestamp;
37+
u64 cgroup_id;
38+
char otype[OTYPE_SIZE];
39+
};
40+
41+
struct rename_data_t
42+
{
43+
u32 pid;
44+
u32 uid;
45+
char old_filename[FILE_NAME_SIZE];
46+
char new_filename[FILE_NAME_SIZE];
47+
char comm[COMM_SIZE];
2848
u64 timestamp;
29-
char otype[16];
30-
};
49+
u64 cgroup_id;
50+
char otype[OTYPE_SIZE];
51+
};
52+
53+
#endif

headers.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,9 @@
77
#include <bpf/bpf_tracing.h>
88
#include <bpf/bpf_endian.h>
99

10+
#define FILE_NAME_SIZE 144
11+
#define OTYPE_SIZE 16
12+
#define COMM_SIZE 32
13+
#define DCACHE_NEGATIVE_DENTRY 0x0020
1014

1115
#endif

helpers/delete.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#ifndef DELETE_H
2+
#define DELETE_H
3+
4+
#include "../headers.h"
5+
#include "../data_types.h"
6+
7+
static __always_inline int trace_file_delete(struct pt_regs *ctx, struct dentry *de)
8+
{
9+
if (!de)
10+
{
11+
bpf_trace_printk("trace_file_delete: dentry is NULL\n", sizeof("trace_file_delete: dentry is NULL\n"));
12+
return 0;
13+
}
14+
15+
struct data_t *data = bpf_ringbuf_reserve(&events, sizeof(struct data_t), 0);
16+
if (!data)
17+
{
18+
bpf_trace_printk("trace_file_delete: failed to reserve ringbuf\n", sizeof("trace_file_delete: failed to reserve ringbuf\n"));
19+
return 0;
20+
}
21+
__builtin_memset(data, 0, sizeof(*data));
22+
23+
struct qstr d_name_qstr = {};
24+
bpf_core_read(&d_name_qstr, sizeof(d_name_qstr), &de->d_name);
25+
26+
if (d_name_qstr.len <= 0 || !d_name_qstr.name || d_name_qstr.name == (void *)-1UL || d_name_qstr.name == NULL)
27+
{
28+
bpf_ringbuf_discard(data, 0);
29+
return 0;
30+
}
31+
32+
unsigned char d_flags = 0;
33+
bpf_core_read(&d_flags, sizeof(d_flags), &de->d_flags);
34+
if (d_flags & DCACHE_NEGATIVE_DENTRY) {
35+
bpf_trace_printk("trace_file_delete: negative dentry detected (file likely non-existent). Discarding.\n", sizeof("trace_file_delete: negative dentry detected (file likely non-existent). Discarding.\n"));
36+
bpf_ringbuf_discard(data, 0);
37+
return 0;
38+
}
39+
40+
char fname[FILE_NAME_SIZE] = {};
41+
bpf_core_read_str(fname, sizeof(fname), d_name_qstr.name);
42+
43+
char OPRN[] = "DELETE";
44+
__builtin_memcpy(data->filename, fname, sizeof(data->filename));
45+
__builtin_memcpy(data->otype, OPRN, sizeof(data->otype));
46+
data->pid = bpf_get_current_pid_tgid() >> 32;
47+
data->uid = bpf_get_current_uid_gid();
48+
data->timestamp = bpf_ktime_get_ns();
49+
50+
bpf_get_current_comm(&data->comm, sizeof(data->comm));
51+
52+
int cgroup_id = bpf_get_current_cgroup_id();
53+
data->cgroup_id = cgroup_id;
54+
55+
bpf_ringbuf_submit(data, 0);
56+
return 0;
57+
}
58+
59+
#endif

0 commit comments

Comments
 (0)