pinctrl: qcom: Don't clear pending interrupts when enabling
[sfrench/cifs-2.6.git] / tools / testing / selftests / bpf / progs / local_storage.c
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 int monitored_pid = 0;
17 int inode_storage_result = -1;
18 int sk_storage_result = -1;
19
20 struct local_storage {
21         struct inode *exec_inode;
22         __u32 value;
23         struct bpf_spin_lock lock;
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_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
47 SEC("lsm/inode_unlink")
48 int 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         int err;
54
55         if (pid != monitored_pid)
56                 return 0;
57
58         storage = bpf_task_storage_get(&task_storage_map,
59                                        bpf_get_current_task_btf(), 0, 0);
60         if (storage) {
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);
65                 if (is_self_unlink)
66                         return -EPERM;
67         }
68
69         storage = bpf_inode_storage_get(&inode_storage_map, victim->d_inode, 0,
70                                         BPF_LOCAL_STORAGE_GET_F_CREATE);
71         if (!storage)
72                 return 0;
73
74         bpf_spin_lock(&storage->lock);
75         if (storage->value != DUMMY_STORAGE_VALUE)
76                 inode_storage_result = -1;
77         bpf_spin_unlock(&storage->lock);
78
79         err = bpf_inode_storage_delete(&inode_storage_map, victim->d_inode);
80         if (!err)
81                 inode_storage_result = err;
82
83         return 0;
84 }
85
86 SEC("lsm/socket_bind")
87 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address,
88              int addrlen)
89 {
90         __u32 pid = bpf_get_current_pid_tgid() >> 32;
91         struct local_storage *storage;
92         int err;
93
94         if (pid != monitored_pid)
95                 return 0;
96
97         storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0,
98                                      BPF_LOCAL_STORAGE_GET_F_CREATE);
99         if (!storage)
100                 return 0;
101
102         bpf_spin_lock(&storage->lock);
103         if (storage->value != DUMMY_STORAGE_VALUE)
104                 sk_storage_result = -1;
105         bpf_spin_unlock(&storage->lock);
106
107         err = bpf_sk_storage_delete(&sk_storage_map, sock->sk);
108         if (!err)
109                 sk_storage_result = err;
110
111         return 0;
112 }
113
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)
117 {
118         __u32 pid = bpf_get_current_pid_tgid() >> 32;
119         struct local_storage *storage;
120
121         if (pid != monitored_pid)
122                 return 0;
123
124         storage = bpf_sk_storage_get(&sk_storage_map, sock->sk, 0,
125                                      BPF_LOCAL_STORAGE_GET_F_CREATE);
126         if (!storage)
127                 return 0;
128
129         bpf_spin_lock(&storage->lock);
130         storage->value = DUMMY_STORAGE_VALUE;
131         bpf_spin_unlock(&storage->lock);
132
133         return 0;
134 }
135
136 SEC("lsm/file_open")
137 int BPF_PROG(file_open, struct file *file)
138 {
139         __u32 pid = bpf_get_current_pid_tgid() >> 32;
140         struct local_storage *storage;
141
142         if (pid != monitored_pid)
143                 return 0;
144
145         if (!file->f_inode)
146                 return 0;
147
148         storage = bpf_inode_storage_get(&inode_storage_map, file->f_inode, 0,
149                                         BPF_LOCAL_STORAGE_GET_F_CREATE);
150         if (!storage)
151                 return 0;
152
153         bpf_spin_lock(&storage->lock);
154         storage->value = DUMMY_STORAGE_VALUE;
155         bpf_spin_unlock(&storage->lock);
156         return 0;
157 }
158
159 /* This uses the local storage to remember the inode of the binary that a
160  * process was originally executing.
161  */
162 SEC("lsm/bprm_committed_creds")
163 void BPF_PROG(exec, struct linux_binprm *bprm)
164 {
165         struct local_storage *storage;
166
167         storage = bpf_task_storage_get(&task_storage_map,
168                                        bpf_get_current_task_btf(), 0,
169                                        BPF_LOCAL_STORAGE_GET_F_CREATE);
170         if (storage) {
171                 bpf_spin_lock(&storage->lock);
172                 storage->exec_inode = bprm->file->f_inode;
173                 bpf_spin_unlock(&storage->lock);
174         }
175 }