~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/progs/local_storage.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 
  3 /*
  4  * Copyright 2020 Google LLC.
  5  */
  6 
  7 #include "vmlinux.h"
  8 #include <errno.h>
  9 #include <bpf/bpf_helpers.h>
 10 #include <bpf/bpf_tracing.h>
 11 
 12 char _license[] SEC("license") = "GPL";
 13 
 14 #define DUMMY_STORAGE_VALUE 0xdeadbeef
 15 
 16 __u32 monitored_pid = 0;
 17 int inode_storage_result = -1;
 18 int sk_storage_result = -1;
 19 int task_storage_result = -1;
 20 
 21 struct local_storage {
 22         struct inode *exec_inode;
 23         __u32 value;
 24 };
 25 
 26 struct {
 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 
 33 struct {
 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 
 40 struct {
 41         __uint(type, BPF_MAP_TYPE_SK_STORAGE);
 42         __uint(map_flags, BPF_F_NO_PREALLOC | BPF_F_CLONE);
 43         __type(key, int);
 44         __type(value, struct local_storage);
 45 } sk_storage_map2 SEC(".maps");
 46 
 47 struct {
 48         __uint(type, BPF_MAP_TYPE_TASK_STORAGE);
 49         __uint(map_flags, BPF_F_NO_PREALLOC);
 50         __type(key, int);
 51         __type(value, struct local_storage);
 52 } task_storage_map SEC(".maps");
 53 
 54 struct {
 55         __uint(type, BPF_MAP_TYPE_TASK_STORAGE);
 56         __uint(map_flags, BPF_F_NO_PREALLOC);
 57         __type(key, int);
 58         __type(value, struct local_storage);
 59 } task_storage_map2 SEC(".maps");
 60 
 61 SEC("lsm/inode_unlink")
 62 int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim)
 63 {
 64         __u32 pid = bpf_get_current_pid_tgid() >> 32;
 65         struct bpf_local_storage *local_storage;
 66         struct local_storage *storage;
 67         struct task_struct *task;
 68         bool is_self_unlink;
 69 
 70         if (pid != monitored_pid)
 71                 return 0;
 72 
 73         task = bpf_get_current_task_btf();
 74         if (!task)
 75                 return 0;
 76 
 77         task_storage_result = -1;
 78 
 79         storage = bpf_task_storage_get(&task_storage_map, task, 0, 0);
 80         if (!storage)
 81                 return 0;
 82 
 83         /* Don't let an executable delete itself */
 84         is_self_unlink = storage->exec_inode == victim->d_inode;
 85 
 86         storage = bpf_task_storage_get(&task_storage_map2, task, 0,
 87                                        BPF_LOCAL_STORAGE_GET_F_CREATE);
 88         if (!storage || storage->value)
 89                 return 0;
 90 
 91         if (bpf_task_storage_delete(&task_storage_map, task))
 92                 return 0;
 93 
 94         /* Ensure that the task_storage_map is disconnected from the storage.
 95          * The storage memory should not be freed back to the
 96          * bpf_mem_alloc.
 97          */
 98         local_storage = task->bpf_storage;
 99         if (!local_storage || local_storage->smap)
100                 return 0;
101 
102         task_storage_result = 0;
103 
104         return is_self_unlink ? -EPERM : 0;
105 }
106 
107 SEC("lsm.s/inode_rename")
108 int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
109              struct inode *new_dir, struct dentry *new_dentry,
110              unsigned int flags)
111 {
112         struct local_storage *storage;
113         int err;
114 
115         /* new_dentry->d_inode can be NULL when the inode is renamed to a file
116          * that did not exist before. The helper should be able to handle this
117          * NULL pointer.
118          */
119         bpf_inode_storage_get(&inode_storage_map, new_dentry->d_inode, 0,
120                               BPF_LOCAL_STORAGE_GET_F_CREATE);
121 
122         storage = bpf_inode_storage_get(&inode_storage_map, old_dentry->d_inode,
123                                         0, 0);
124         if (!storage)
125                 return 0;
126 
127         if (storage->value != DUMMY_STORAGE_VALUE)
128                 inode_storage_result = -1;
129 
130         err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);
131         if (!err)
132                 inode_storage_result = err;
133 
134         return 0;
135 }
136 
137 SEC("lsm.s/socket_bind")
138 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,
139              int addrlen)
140 {
141         __u32 pid = bpf_get_current_pid_tgid() >> 32;
142         struct local_storage *storage;
143         struct sock *sk = sock->sk;
144 
145         if (pid != monitored_pid || !sk)
146                 return 0;
147 
148         storage = bpf_sk_storage_get(&sk_storage_map, sk, 0, 0);
149         if (!storage)
150                 return 0;
151 
152         sk_storage_result = -1;
153         if (storage->value != DUMMY_STORAGE_VALUE)
154                 return 0;
155 
156         /* This tests that we can associate multiple elements
157          * with the local storage.
158          */
159         storage = bpf_sk_storage_get(&sk_storage_map2, sk, 0,
160                                      BPF_LOCAL_STORAGE_GET_F_CREATE);
161         if (!storage)
162                 return 0;
163 
164         if (bpf_sk_storage_delete(&sk_storage_map2, sk))
165                 return 0;
166 
167         storage = bpf_sk_storage_get(&sk_storage_map2, sk, 0,
168                                      BPF_LOCAL_STORAGE_GET_F_CREATE);
169         if (!storage)
170                 return 0;
171 
172         if (bpf_sk_storage_delete(&sk_storage_map, sk))
173                 return 0;
174 
175         /* Ensure that the sk_storage_map is disconnected from the storage. */
176         if (!sk->sk_bpf_storage || sk->sk_bpf_storage->smap)
177                 return 0;
178 
179         sk_storage_result = 0;
180         return 0;
181 }
182 
183 SEC("lsm.s/socket_post_create")
184 int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,
185              int protocol, int kern)
186 {
187         __u32 pid = bpf_get_current_pid_tgid() >> 32;
188         struct local_storage *storage;
189         struct sock *sk = sock->sk;
190 
191         if (pid != monitored_pid || !sk)
192                 return 0;
193 
194         storage = bpf_sk_storage_get(&sk_storage_map, sk, 0,
195                                      BPF_LOCAL_STORAGE_GET_F_CREATE);
196         if (!storage)
197                 return 0;
198 
199         storage->value = DUMMY_STORAGE_VALUE;
200 
201         return 0;
202 }
203 
204 /* This uses the local storage to remember the inode of the binary that a
205  * process was originally executing.
206  */
207 SEC("lsm.s/bprm_committed_creds")
208 void BPF_PROG(exec, struct linux_binprm *bprm)
209 {
210         __u32 pid = bpf_get_current_pid_tgid() >> 32;
211         struct local_storage *storage;
212 
213         if (pid != monitored_pid)
214                 return;
215 
216         storage = bpf_task_storage_get(&task_storage_map,
217                                        bpf_get_current_task_btf(), 0,
218                                        BPF_LOCAL_STORAGE_GET_F_CREATE);
219         if (storage)
220                 storage->exec_inode = bprm->file->f_inode;
221 
222         storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,
223                                         0, BPF_LOCAL_STORAGE_GET_F_CREATE);
224         if (!storage)
225                 return;
226 
227         storage->value = DUMMY_STORAGE_VALUE;
228 }
229 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php