1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright 2020 Google LLC.
9 #include <bpf/bpf_helpers.h>
10 #include <bpf/bpf_tracing.h>
12 char _license
[] SEC("license") = "GPL";
14 #define DUMMY_STORAGE_VALUE 0xdeadbeef
16 int monitored_pid
= 0;
17 int inode_storage_result
= -1;
18 int sk_storage_result
= -1;
20 struct local_storage
{
21 struct inode
*exec_inode
;
23 struct bpf_spin_lock lock
;
27 __uint(type
, BPF_MAP_TYPE_INODE_STORAGE
);
28 __uint(map_flags
, BPF_F_NO_PREALLOC
);
30 __type(value
, struct local_storage
);
31 } inode_storage_map
SEC(".maps");
34 __uint(type
, BPF_MAP_TYPE_SK_STORAGE
);
35 __uint(map_flags
, BPF_F_NO_PREALLOC
| BPF_F_CLONE
);
37 __type(value
, struct local_storage
);
38 } sk_storage_map
SEC(".maps");
41 __uint(type
, BPF_MAP_TYPE_TASK_STORAGE
);
42 __uint(map_flags
, BPF_F_NO_PREALLOC
);
44 __type(value
, struct local_storage
);
45 } task_storage_map
SEC(".maps");
47 SEC("lsm/inode_unlink")
48 int BPF_PROG(unlink_hook
, struct inode
*dir
, struct dentry
*victim
)
50 __u32 pid
= bpf_get_current_pid_tgid() >> 32;
51 struct local_storage
*storage
;
55 if (pid
!= monitored_pid
)
58 storage
= bpf_task_storage_get(&task_storage_map
,
59 bpf_get_current_task_btf(), 0, 0);
61 /* Don't let an executable delete itself */
62 bpf_spin_lock(&storage
->lock
);
63 is_self_unlink
= storage
->exec_inode
== victim
->d_inode
;
64 bpf_spin_unlock(&storage
->lock
);
69 storage
= bpf_inode_storage_get(&inode_storage_map
, victim
->d_inode
, 0,
70 BPF_LOCAL_STORAGE_GET_F_CREATE
);
74 bpf_spin_lock(&storage
->lock
);
75 if (storage
->value
!= DUMMY_STORAGE_VALUE
)
76 inode_storage_result
= -1;
77 bpf_spin_unlock(&storage
->lock
);
79 err
= bpf_inode_storage_delete(&inode_storage_map
, victim
->d_inode
);
81 inode_storage_result
= err
;
86 SEC("lsm/socket_bind")
87 int BPF_PROG(socket_bind
, struct socket
*sock
, struct sockaddr
*address
,
90 __u32 pid
= bpf_get_current_pid_tgid() >> 32;
91 struct local_storage
*storage
;
94 if (pid
!= monitored_pid
)
97 storage
= bpf_sk_storage_get(&sk_storage_map
, sock
->sk
, 0,
98 BPF_LOCAL_STORAGE_GET_F_CREATE
);
102 bpf_spin_lock(&storage
->lock
);
103 if (storage
->value
!= DUMMY_STORAGE_VALUE
)
104 sk_storage_result
= -1;
105 bpf_spin_unlock(&storage
->lock
);
107 err
= bpf_sk_storage_delete(&sk_storage_map
, sock
->sk
);
109 sk_storage_result
= err
;
114 SEC("lsm/socket_post_create")
115 int BPF_PROG(socket_post_create
, struct socket
*sock
, int family
, int type
,
116 int protocol
, int kern
)
118 __u32 pid
= bpf_get_current_pid_tgid() >> 32;
119 struct local_storage
*storage
;
121 if (pid
!= monitored_pid
)
124 storage
= bpf_sk_storage_get(&sk_storage_map
, sock
->sk
, 0,
125 BPF_LOCAL_STORAGE_GET_F_CREATE
);
129 bpf_spin_lock(&storage
->lock
);
130 storage
->value
= DUMMY_STORAGE_VALUE
;
131 bpf_spin_unlock(&storage
->lock
);
137 int BPF_PROG(file_open
, struct file
*file
)
139 __u32 pid
= bpf_get_current_pid_tgid() >> 32;
140 struct local_storage
*storage
;
142 if (pid
!= monitored_pid
)
148 storage
= bpf_inode_storage_get(&inode_storage_map
, file
->f_inode
, 0,
149 BPF_LOCAL_STORAGE_GET_F_CREATE
);
153 bpf_spin_lock(&storage
->lock
);
154 storage
->value
= DUMMY_STORAGE_VALUE
;
155 bpf_spin_unlock(&storage
->lock
);
159 /* This uses the local storage to remember the inode of the binary that a
160 * process was originally executing.
162 SEC("lsm/bprm_committed_creds")
163 void BPF_PROG(exec
, struct linux_binprm
*bprm
)
165 struct local_storage
*storage
;
167 storage
= bpf_task_storage_get(&task_storage_map
,
168 bpf_get_current_task_btf(), 0,
169 BPF_LOCAL_STORAGE_GET_F_CREATE
);
171 bpf_spin_lock(&storage
->lock
);
172 storage
->exec_inode
= bprm
->file
->f_inode
;
173 bpf_spin_unlock(&storage
->lock
);