1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020 Facebook
4 * Copyright 2020 Google LLC.
8 #include <linux/sched.h>
9 #include <linux/rculist.h>
10 #include <linux/list.h>
11 #include <linux/hash.h>
12 #include <linux/types.h>
13 #include <linux/spinlock.h>
14 #include <linux/bpf.h>
15 #include <linux/bpf_local_storage.h>
16 #include <linux/filter.h>
17 #include <uapi/linux/btf.h>
18 #include <linux/bpf_lsm.h>
19 #include <linux/btf_ids.h>
20 #include <linux/fdtable.h>
22 DEFINE_BPF_STORAGE_CACHE(task_cache
);
24 static struct bpf_local_storage __rcu
**task_storage_ptr(void *owner
)
26 struct task_struct
*task
= owner
;
27 struct bpf_storage_blob
*bsb
;
35 static struct bpf_local_storage_data
*
36 task_storage_lookup(struct task_struct
*task
, struct bpf_map
*map
,
39 struct bpf_local_storage
*task_storage
;
40 struct bpf_local_storage_map
*smap
;
41 struct bpf_storage_blob
*bsb
;
47 task_storage
= rcu_dereference(bsb
->storage
);
51 smap
= (struct bpf_local_storage_map
*)map
;
52 return bpf_local_storage_lookup(task_storage
, smap
, cacheit_lockit
);
55 void bpf_task_storage_free(struct task_struct
*task
)
57 struct bpf_local_storage_elem
*selem
;
58 struct bpf_local_storage
*local_storage
;
59 bool free_task_storage
= false;
60 struct bpf_storage_blob
*bsb
;
69 local_storage
= rcu_dereference(bsb
->storage
);
75 /* Neither the bpf_prog nor the bpf-map's syscall
76 * could be modifying the local_storage->list now.
77 * Thus, no elem can be added-to or deleted-from the
78 * local_storage->list by the bpf_prog or by the bpf-map's syscall.
80 * It is racing with bpf_local_storage_map_free() alone
81 * when unlinking elem from the local_storage->list and
82 * the map's bucket->list.
84 raw_spin_lock_bh(&local_storage
->lock
);
85 hlist_for_each_entry_safe(selem
, n
, &local_storage
->list
, snode
) {
86 /* Always unlink from map before unlinking from
89 bpf_selem_unlink_map(selem
);
90 free_task_storage
= bpf_selem_unlink_storage_nolock(
91 local_storage
, selem
, false);
93 raw_spin_unlock_bh(&local_storage
->lock
);
96 /* free_task_storage should always be true as long as
97 * local_storage->list was non-empty.
99 if (free_task_storage
)
100 kfree_rcu(local_storage
, rcu
);
103 static void *bpf_pid_task_storage_lookup_elem(struct bpf_map
*map
, void *key
)
105 struct bpf_local_storage_data
*sdata
;
106 struct task_struct
*task
;
107 unsigned int f_flags
;
112 pid
= pidfd_get_pid(fd
, &f_flags
);
114 return ERR_CAST(pid
);
116 /* We should be in an RCU read side critical section, it should be safe
119 WARN_ON_ONCE(!rcu_read_lock_held());
120 task
= pid_task(pid
, PIDTYPE_PID
);
126 sdata
= task_storage_lookup(task
, map
, true);
128 return sdata
? sdata
->data
: NULL
;
134 static int bpf_pid_task_storage_update_elem(struct bpf_map
*map
, void *key
,
135 void *value
, u64 map_flags
)
137 struct bpf_local_storage_data
*sdata
;
138 struct task_struct
*task
;
139 unsigned int f_flags
;
144 pid
= pidfd_get_pid(fd
, &f_flags
);
148 /* We should be in an RCU read side critical section, it should be safe
151 WARN_ON_ONCE(!rcu_read_lock_held());
152 task
= pid_task(pid
, PIDTYPE_PID
);
153 if (!task
|| !task_storage_ptr(task
)) {
158 sdata
= bpf_local_storage_update(
159 task
, (struct bpf_local_storage_map
*)map
, value
, map_flags
);
161 err
= PTR_ERR_OR_ZERO(sdata
);
167 static int task_storage_delete(struct task_struct
*task
, struct bpf_map
*map
)
169 struct bpf_local_storage_data
*sdata
;
171 sdata
= task_storage_lookup(task
, map
, false);
175 bpf_selem_unlink(SELEM(sdata
));
180 static int bpf_pid_task_storage_delete_elem(struct bpf_map
*map
, void *key
)
182 struct task_struct
*task
;
183 unsigned int f_flags
;
188 pid
= pidfd_get_pid(fd
, &f_flags
);
192 /* We should be in an RCU read side critical section, it should be safe
195 WARN_ON_ONCE(!rcu_read_lock_held());
196 task
= pid_task(pid
, PIDTYPE_PID
);
202 err
= task_storage_delete(task
, map
);
208 BPF_CALL_4(bpf_task_storage_get
, struct bpf_map
*, map
, struct task_struct
*,
209 task
, void *, value
, u64
, flags
)
211 struct bpf_local_storage_data
*sdata
;
213 if (flags
& ~(BPF_LOCAL_STORAGE_GET_F_CREATE
))
214 return (unsigned long)NULL
;
216 /* explicitly check that the task_storage_ptr is not
217 * NULL as task_storage_lookup returns NULL in this case and
218 * bpf_local_storage_update expects the owner to have a
219 * valid storage pointer.
221 if (!task_storage_ptr(task
))
222 return (unsigned long)NULL
;
224 sdata
= task_storage_lookup(task
, map
, true);
226 return (unsigned long)sdata
->data
;
228 /* This helper must only be called from places where the lifetime of the task
229 * is guaranteed. Either by being refcounted or by being protected
230 * by an RCU read-side critical section.
232 if (flags
& BPF_LOCAL_STORAGE_GET_F_CREATE
) {
233 sdata
= bpf_local_storage_update(
234 task
, (struct bpf_local_storage_map
*)map
, value
,
236 return IS_ERR(sdata
) ? (unsigned long)NULL
:
237 (unsigned long)sdata
->data
;
240 return (unsigned long)NULL
;
243 BPF_CALL_2(bpf_task_storage_delete
, struct bpf_map
*, map
, struct task_struct
*,
246 /* This helper must only be called from places where the lifetime of the task
247 * is guaranteed. Either by being refcounted or by being protected
248 * by an RCU read-side critical section.
250 return task_storage_delete(task
, map
);
253 static int notsupp_get_next_key(struct bpf_map
*map
, void *key
, void *next_key
)
258 static struct bpf_map
*task_storage_map_alloc(union bpf_attr
*attr
)
260 struct bpf_local_storage_map
*smap
;
262 smap
= bpf_local_storage_map_alloc(attr
);
264 return ERR_CAST(smap
);
266 smap
->cache_idx
= bpf_local_storage_cache_idx_get(&task_cache
);
270 static void task_storage_map_free(struct bpf_map
*map
)
272 struct bpf_local_storage_map
*smap
;
274 smap
= (struct bpf_local_storage_map
*)map
;
275 bpf_local_storage_cache_idx_free(&task_cache
, smap
->cache_idx
);
276 bpf_local_storage_map_free(smap
);
279 static int task_storage_map_btf_id
;
280 const struct bpf_map_ops task_storage_map_ops
= {
281 .map_meta_equal
= bpf_map_meta_equal
,
282 .map_alloc_check
= bpf_local_storage_map_alloc_check
,
283 .map_alloc
= task_storage_map_alloc
,
284 .map_free
= task_storage_map_free
,
285 .map_get_next_key
= notsupp_get_next_key
,
286 .map_lookup_elem
= bpf_pid_task_storage_lookup_elem
,
287 .map_update_elem
= bpf_pid_task_storage_update_elem
,
288 .map_delete_elem
= bpf_pid_task_storage_delete_elem
,
289 .map_check_btf
= bpf_local_storage_map_check_btf
,
290 .map_btf_name
= "bpf_local_storage_map",
291 .map_btf_id
= &task_storage_map_btf_id
,
292 .map_owner_storage_ptr
= task_storage_ptr
,
295 BTF_ID_LIST_SINGLE(bpf_task_storage_btf_ids
, struct, task_struct
)
297 const struct bpf_func_proto bpf_task_storage_get_proto
= {
298 .func
= bpf_task_storage_get
,
300 .ret_type
= RET_PTR_TO_MAP_VALUE_OR_NULL
,
301 .arg1_type
= ARG_CONST_MAP_PTR
,
302 .arg2_type
= ARG_PTR_TO_BTF_ID
,
303 .arg2_btf_id
= &bpf_task_storage_btf_ids
[0],
304 .arg3_type
= ARG_PTR_TO_MAP_VALUE_OR_NULL
,
305 .arg4_type
= ARG_ANYTHING
,
308 const struct bpf_func_proto bpf_task_storage_delete_proto
= {
309 .func
= bpf_task_storage_delete
,
311 .ret_type
= RET_INTEGER
,
312 .arg1_type
= ARG_CONST_MAP_PTR
,
313 .arg2_type
= ARG_PTR_TO_BTF_ID
,
314 .arg2_btf_id
= &bpf_task_storage_btf_ids
[0],