-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmain.c
More file actions
127 lines (105 loc) · 2.81 KB
/
main.c
File metadata and controls
127 lines (105 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// clang-format off
#include "vmlinux.h"
#include "file.h"
#include "types.h"
#include "inode.h"
#include "maps.h"
#include "events.h"
#include "bound_path.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>
// clang-format on
char _license[] SEC("license") = "Dual MIT/GPL";
#define FMODE_WRITE ((fmode_t)(1 << 1))
#define FMODE_PWRITE ((fmode_t)(1 << 4))
#define FMODE_CREATED ((fmode_t)(1 << 20))
SEC("lsm/file_open")
int BPF_PROG(trace_file_open, struct file* file) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
}
m->file_open.total++;
file_activity_type_t event_type = FILE_ACTIVITY_INIT;
if ((file->f_mode & FMODE_CREATED) != 0) {
event_type = FILE_ACTIVITY_CREATION;
} else if ((file->f_mode & (FMODE_WRITE | FMODE_PWRITE)) != 0) {
event_type = FILE_ACTIVITY_OPEN;
} else {
goto ignored;
}
struct bound_path_t* path = path_read(&file->f_path);
if (path == NULL) {
bpf_printk("Failed to read path");
m->file_open.error++;
return 0;
}
inode_key_t inode_key = inode_to_key(file->f_inode);
const inode_value_t* inode = inode_get(&inode_key);
switch (inode_is_monitored(inode)) {
case NOT_MONITORED:
if (!is_monitored(path)) {
goto ignored;
}
break;
case MONITORED:
break;
}
submit_event(&m->file_open, event_type, path->path, &inode_key, true);
return 0;
ignored:
m->file_open.ignored++;
return 0;
}
SEC("lsm/path_unlink")
int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
}
m->path_unlink.total++;
struct bound_path_t* path = NULL;
if (path_unlink_supports_bpf_d_path) {
path = path_read(dir);
} else {
path = path_read_no_d_path(dir);
}
if (path == NULL) {
bpf_printk("Failed to read path");
goto error;
}
path_write_char(path->path, path->len - 1, '/');
switch (path_append_dentry(path, dentry)) {
case PATH_APPEND_SUCCESS:
break;
case PATH_APPEND_INVALID_LENGTH:
bpf_printk("Invalid path length: %u", path->len);
goto error;
case PATH_APPEND_READ_ERROR:
bpf_printk("Failed to read final path component");
goto error;
}
inode_key_t inode_key = inode_to_key(dentry->d_inode);
const inode_value_t* inode = inode_get(&inode_key);
switch (inode_is_monitored(inode)) {
case NOT_MONITORED:
if (!is_monitored(path)) {
m->path_unlink.ignored++;
return 0;
}
break;
case MONITORED:
inode_remove(&inode_key);
break;
}
submit_event(&m->path_unlink,
FILE_ACTIVITY_UNLINK,
path->path,
&inode_key,
path_unlink_supports_bpf_d_path);
return 0;
error:
m->path_unlink.error++;
return 0;
}