1
2
3
4
5
6
7#include "vmlinux.h"
8#include <errno.h>
9#include <bpf/bpf_helpers.h>
10#include <bpf/bpf_tracing.h>
11
12char _license[] SEC("license") = "GPL";
13
14#define DUMMY_STORAGE_VALUE 0xdeadbeef
15
16int monitored_pid = 0;
17int inode_storage_result = -1;
18int sk_storage_result = -1;
19
20struct local_storage {
21 struct inode *exec_inode;
22 __u32 value;
23 struct bpf_spin_lock lock;
24};
25
26struct {
27 __uint(type, BPF_MAP_TYPE_INODE_STORAGE);
28 __uint(map_flags, BPF_F_NO_PREALLOC);
29 __type(key, int);
30 __type(value, struct local_storage);
31} inode_storage_map SEC(".maps");
32
33struct {
34 __uint(type, BPF_MAP_TYPE_SK_STORAGE);
35 __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE);
36 __type(key, int);
37 __type(value, struct local_storage);
38} sk_storage_map SEC(".maps");
39
40struct {
41 __uint(type, BPF_MAP_TYPE_TASK_STORAGE);
42 __uint(map_flags, BPF_F_NO_PREALLOC);
43 __type(key, int);
44 __type(value, struct local_storage);
45} task_storage_map SEC(".maps");
46
47SEC("lsm/inode_unlink")
48int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim)
49{
50 __u32 pid = bpf_get_current_pid_tgid() >> 32;
51 struct local_storage *storage;
52 bool is_self_unlink;
53
54 if (pid != monitored_pid)
55 return 0;
56
57 storage = bpf_task_storage_get(&task_storage_map,
58 bpf_get_current_task_btf(), 0, 0);
59 if (storage) {
60
61 bpf_spin_lock(&storage->lock);
62 is_self_unlink = storage->exec_inode == victim->d_inode;
63 bpf_spin_unlock(&storage->lock);
64 if (is_self_unlink)
65 return -EPERM;
66 }
67
68 return 0;
69}
70
71SEC("lsm/inode_rename")
72int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
73 struct inode *new_dir, struct dentry *new_dentry,
74 unsigned int flags)
75{
76 __u32 pid = bpf_get_current_pid_tgid() >> 32;
77 struct local_storage *storage;
78 int err;
79
80
81
82
83
84 bpf_inode_storage_get(&inode_storage_map, new_dentry->d_inode, 0,
85 BPF_LOCAL_STORAGE_GET_F_CREATE);
86
87 storage = bpf_inode_storage_get(&inode_storage_map, old_dentry->d_inode,
88 0, 0);
89 if (!storage)
90 return 0;
91
92 bpf_spin_lock(&storage->lock);
93 if (storage->value != DUMMY_STORAGE_VALUE)
94 inode_storage_result = -1;
95 bpf_spin_unlock(&storage->lock);
96
97 err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);
98 if (!err)
99 inode_storage_result = err;
100
101 return 0;
102}
103
104SEC("lsm/socket_bind")
105int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,
106 int addrlen)
107{
108 __u32 pid = bpf_get_current_pid_tgid() >> 32;
109 struct local_storage *storage;
110 int err;
111
112 if (pid != monitored_pid)
113 return 0;
114
115 storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0,
116 BPF_LOCAL_STORAGE_GET_F_CREATE);
117 if (!storage)
118 return 0;
119
120 bpf_spin_lock(&storage->lock);
121 if (storage->value != DUMMY_STORAGE_VALUE)
122 sk_storage_result = -1;
123 bpf_spin_unlock(&storage->lock);
124
125 err = bpf_sk_storage_delete(&sk_storage_map, sock->sk);
126 if (!err)
127 sk_storage_result = err;
128
129 return 0;
130}
131
132SEC("lsm/socket_post_create")
133int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,
134 int protocol, int kern)
135{
136 __u32 pid = bpf_get_current_pid_tgid() >> 32;
137 struct local_storage *storage;
138
139 if (pid != monitored_pid)
140 return 0;
141
142 storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0,
143 BPF_LOCAL_STORAGE_GET_F_CREATE);
144 if (!storage)
145 return 0;
146
147 bpf_spin_lock(&storage->lock);
148 storage->value = DUMMY_STORAGE_VALUE;
149 bpf_spin_unlock(&storage->lock);
150
151 return 0;
152}
153
154
155
156
157SEC("lsm/bprm_committed_creds")
158void BPF_PROG(exec, struct linux_binprm *bprm)
159{
160 __u32 pid = bpf_get_current_pid_tgid() >> 32;
161 struct local_storage *storage;
162
163 if (pid != monitored_pid)
164 return;
165
166 storage = bpf_task_storage_get(&task_storage_map,
167 bpf_get_current_task_btf(), 0,
168 BPF_LOCAL_STORAGE_GET_F_CREATE);
169 if (storage) {
170 bpf_spin_lock(&storage->lock);
171 storage->exec_inode = bprm->file->f_inode;
172 bpf_spin_unlock(&storage->lock);
173 }
174
175 storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,
176 0, BPF_LOCAL_STORAGE_GET_F_CREATE);
177 if (!storage)
178 return;
179
180 bpf_spin_lock(&storage->lock);
181 storage->value = DUMMY_STORAGE_VALUE;
182 bpf_spin_unlock(&storage->lock);
183}
184