bpf_task_storage.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2020 Facebook
  4. * Copyright 2020 Google LLC.
  5. */
  6. #include <linux/pid.h>
  7. #include <linux/sched.h>
  8. #include <linux/rculist.h>
  9. #include <linux/list.h>
  10. #include <linux/hash.h>
  11. #include <linux/types.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/bpf.h>
  14. #include <linux/bpf_local_storage.h>
  15. #include <linux/filter.h>
  16. #include <uapi/linux/btf.h>
  17. #include <linux/btf_ids.h>
  18. #include <linux/fdtable.h>
  19. #include <linux/rcupdate_trace.h>
  20. DEFINE_BPF_STORAGE_CACHE(task_cache);
  21. static DEFINE_PER_CPU(int, bpf_task_storage_busy);
  22. static void bpf_task_storage_lock(void)
  23. {
  24. migrate_disable();
  25. this_cpu_inc(bpf_task_storage_busy);
  26. }
  27. static void bpf_task_storage_unlock(void)
  28. {
  29. this_cpu_dec(bpf_task_storage_busy);
  30. migrate_enable();
  31. }
  32. static bool bpf_task_storage_trylock(void)
  33. {
  34. migrate_disable();
  35. if (unlikely(this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
  36. this_cpu_dec(bpf_task_storage_busy);
  37. migrate_enable();
  38. return false;
  39. }
  40. return true;
  41. }
  42. static struct bpf_local_storage __rcu **task_storage_ptr(void *owner)
  43. {
  44. struct task_struct *task = owner;
  45. return &task->bpf_storage;
  46. }
  47. static struct bpf_local_storage_data *
  48. task_storage_lookup(struct task_struct *task, struct bpf_map *map,
  49. bool cacheit_lockit)
  50. {
  51. struct bpf_local_storage *task_storage;
  52. struct bpf_local_storage_map *smap;
  53. task_storage =
  54. rcu_dereference_check(task->bpf_storage, bpf_rcu_lock_held());
  55. if (!task_storage)
  56. return NULL;
  57. smap = (struct bpf_local_storage_map *)map;
  58. return bpf_local_storage_lookup(task_storage, smap, cacheit_lockit);
  59. }
  60. void bpf_task_storage_free(struct task_struct *task)
  61. {
  62. struct bpf_local_storage *local_storage;
  63. rcu_read_lock();
  64. local_storage = rcu_dereference(task->bpf_storage);
  65. if (!local_storage) {
  66. rcu_read_unlock();
  67. return;
  68. }
  69. bpf_task_storage_lock();
  70. bpf_local_storage_destroy(local_storage);
  71. bpf_task_storage_unlock();
  72. rcu_read_unlock();
  73. }
  74. static void *bpf_pid_task_storage_lookup_elem(struct bpf_map *map, void *key)
  75. {
  76. struct bpf_local_storage_data *sdata;
  77. struct task_struct *task;
  78. unsigned int f_flags;
  79. struct pid *pid;
  80. int fd, err;
  81. fd = *(int *)key;
  82. pid = pidfd_get_pid(fd, &f_flags);
  83. if (IS_ERR(pid))
  84. return ERR_CAST(pid);
  85. /* We should be in an RCU read side critical section, it should be safe
  86. * to call pid_task.
  87. */
  88. WARN_ON_ONCE(!rcu_read_lock_held());
  89. task = pid_task(pid, PIDTYPE_PID);
  90. if (!task) {
  91. err = -ENOENT;
  92. goto out;
  93. }
  94. bpf_task_storage_lock();
  95. sdata = task_storage_lookup(task, map, true);
  96. bpf_task_storage_unlock();
  97. put_pid(pid);
  98. return sdata ? sdata->data : NULL;
  99. out:
  100. put_pid(pid);
  101. return ERR_PTR(err);
  102. }
  103. static long bpf_pid_task_storage_update_elem(struct bpf_map *map, void *key,
  104. void *value, u64 map_flags)
  105. {
  106. struct bpf_local_storage_data *sdata;
  107. struct task_struct *task;
  108. unsigned int f_flags;
  109. struct pid *pid;
  110. int fd, err;
  111. fd = *(int *)key;
  112. pid = pidfd_get_pid(fd, &f_flags);
  113. if (IS_ERR(pid))
  114. return PTR_ERR(pid);
  115. /* We should be in an RCU read side critical section, it should be safe
  116. * to call pid_task.
  117. */
  118. WARN_ON_ONCE(!rcu_read_lock_held());
  119. task = pid_task(pid, PIDTYPE_PID);
  120. if (!task) {
  121. err = -ENOENT;
  122. goto out;
  123. }
  124. bpf_task_storage_lock();
  125. sdata = bpf_local_storage_update(
  126. task, (struct bpf_local_storage_map *)map, value, map_flags,
  127. GFP_ATOMIC);
  128. bpf_task_storage_unlock();
  129. err = PTR_ERR_OR_ZERO(sdata);
  130. out:
  131. put_pid(pid);
  132. return err;
  133. }
  134. static int task_storage_delete(struct task_struct *task, struct bpf_map *map,
  135. bool nobusy)
  136. {
  137. struct bpf_local_storage_data *sdata;
  138. sdata = task_storage_lookup(task, map, false);
  139. if (!sdata)
  140. return -ENOENT;
  141. if (!nobusy)
  142. return -EBUSY;
  143. bpf_selem_unlink(SELEM(sdata), false);
  144. return 0;
  145. }
  146. static long bpf_pid_task_storage_delete_elem(struct bpf_map *map, void *key)
  147. {
  148. struct task_struct *task;
  149. unsigned int f_flags;
  150. struct pid *pid;
  151. int fd, err;
  152. fd = *(int *)key;
  153. pid = pidfd_get_pid(fd, &f_flags);
  154. if (IS_ERR(pid))
  155. return PTR_ERR(pid);
  156. /* We should be in an RCU read side critical section, it should be safe
  157. * to call pid_task.
  158. */
  159. WARN_ON_ONCE(!rcu_read_lock_held());
  160. task = pid_task(pid, PIDTYPE_PID);
  161. if (!task) {
  162. err = -ENOENT;
  163. goto out;
  164. }
  165. bpf_task_storage_lock();
  166. err = task_storage_delete(task, map, true);
  167. bpf_task_storage_unlock();
  168. out:
  169. put_pid(pid);
  170. return err;
  171. }
  172. /* Called by bpf_task_storage_get*() helpers */
  173. static void *__bpf_task_storage_get(struct bpf_map *map,
  174. struct task_struct *task, void *value,
  175. u64 flags, gfp_t gfp_flags, bool nobusy)
  176. {
  177. struct bpf_local_storage_data *sdata;
  178. sdata = task_storage_lookup(task, map, nobusy);
  179. if (sdata)
  180. return sdata->data;
  181. /* only allocate new storage, when the task is refcounted */
  182. if (refcount_read(&task->usage) &&
  183. (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) && nobusy) {
  184. sdata = bpf_local_storage_update(
  185. task, (struct bpf_local_storage_map *)map, value,
  186. BPF_NOEXIST, gfp_flags);
  187. return IS_ERR(sdata) ? NULL : sdata->data;
  188. }
  189. return NULL;
  190. }
  191. /* *gfp_flags* is a hidden argument provided by the verifier */
  192. BPF_CALL_5(bpf_task_storage_get_recur, struct bpf_map *, map, struct task_struct *,
  193. task, void *, value, u64, flags, gfp_t, gfp_flags)
  194. {
  195. bool nobusy;
  196. void *data;
  197. WARN_ON_ONCE(!bpf_rcu_lock_held());
  198. if (flags & ~BPF_LOCAL_STORAGE_GET_F_CREATE || !task)
  199. return (unsigned long)NULL;
  200. nobusy = bpf_task_storage_trylock();
  201. data = __bpf_task_storage_get(map, task, value, flags,
  202. gfp_flags, nobusy);
  203. if (nobusy)
  204. bpf_task_storage_unlock();
  205. return (unsigned long)data;
  206. }
  207. /* *gfp_flags* is a hidden argument provided by the verifier */
  208. BPF_CALL_5(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,
  209. task, void *, value, u64, flags, gfp_t, gfp_flags)
  210. {
  211. void *data;
  212. WARN_ON_ONCE(!bpf_rcu_lock_held());
  213. if (flags & ~BPF_LOCAL_STORAGE_GET_F_CREATE || !task)
  214. return (unsigned long)NULL;
  215. bpf_task_storage_lock();
  216. data = __bpf_task_storage_get(map, task, value, flags,
  217. gfp_flags, true);
  218. bpf_task_storage_unlock();
  219. return (unsigned long)data;
  220. }
  221. BPF_CALL_2(bpf_task_storage_delete_recur, struct bpf_map *, map, struct task_struct *,
  222. task)
  223. {
  224. bool nobusy;
  225. int ret;
  226. WARN_ON_ONCE(!bpf_rcu_lock_held());
  227. if (!task)
  228. return -EINVAL;
  229. nobusy = bpf_task_storage_trylock();
  230. /* This helper must only be called from places where the lifetime of the task
  231. * is guaranteed. Either by being refcounted or by being protected
  232. * by an RCU read-side critical section.
  233. */
  234. ret = task_storage_delete(task, map, nobusy);
  235. if (nobusy)
  236. bpf_task_storage_unlock();
  237. return ret;
  238. }
  239. BPF_CALL_2(bpf_task_storage_delete, struct bpf_map *, map, struct task_struct *,
  240. task)
  241. {
  242. int ret;
  243. WARN_ON_ONCE(!bpf_rcu_lock_held());
  244. if (!task)
  245. return -EINVAL;
  246. bpf_task_storage_lock();
  247. /* This helper must only be called from places where the lifetime of the task
  248. * is guaranteed. Either by being refcounted or by being protected
  249. * by an RCU read-side critical section.
  250. */
  251. ret = task_storage_delete(task, map, true);
  252. bpf_task_storage_unlock();
  253. return ret;
  254. }
  255. static int notsupp_get_next_key(struct bpf_map *map, void *key, void *next_key)
  256. {
  257. return -ENOTSUPP;
  258. }
  259. static struct bpf_map *task_storage_map_alloc(union bpf_attr *attr)
  260. {
  261. return bpf_local_storage_map_alloc(attr, &task_cache, true);
  262. }
  263. static void task_storage_map_free(struct bpf_map *map)
  264. {
  265. bpf_local_storage_map_free(map, &task_cache, &bpf_task_storage_busy);
  266. }
  267. BTF_ID_LIST_GLOBAL_SINGLE(bpf_local_storage_map_btf_id, struct, bpf_local_storage_map)
  268. const struct bpf_map_ops task_storage_map_ops = {
  269. .map_meta_equal = bpf_map_meta_equal,
  270. .map_alloc_check = bpf_local_storage_map_alloc_check,
  271. .map_alloc = task_storage_map_alloc,
  272. .map_free = task_storage_map_free,
  273. .map_get_next_key = notsupp_get_next_key,
  274. .map_lookup_elem = bpf_pid_task_storage_lookup_elem,
  275. .map_update_elem = bpf_pid_task_storage_update_elem,
  276. .map_delete_elem = bpf_pid_task_storage_delete_elem,
  277. .map_check_btf = bpf_local_storage_map_check_btf,
  278. .map_mem_usage = bpf_local_storage_map_mem_usage,
  279. .map_btf_id = &bpf_local_storage_map_btf_id[0],
  280. .map_owner_storage_ptr = task_storage_ptr,
  281. };
  282. const struct bpf_func_proto bpf_task_storage_get_recur_proto = {
  283. .func = bpf_task_storage_get_recur,
  284. .gpl_only = false,
  285. .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
  286. .arg1_type = ARG_CONST_MAP_PTR,
  287. .arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
  288. .arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
  289. .arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
  290. .arg4_type = ARG_ANYTHING,
  291. };
  292. const struct bpf_func_proto bpf_task_storage_get_proto = {
  293. .func = bpf_task_storage_get,
  294. .gpl_only = false,
  295. .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
  296. .arg1_type = ARG_CONST_MAP_PTR,
  297. .arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
  298. .arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
  299. .arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
  300. .arg4_type = ARG_ANYTHING,
  301. };
  302. const struct bpf_func_proto bpf_task_storage_delete_recur_proto = {
  303. .func = bpf_task_storage_delete_recur,
  304. .gpl_only = false,
  305. .ret_type = RET_INTEGER,
  306. .arg1_type = ARG_CONST_MAP_PTR,
  307. .arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
  308. .arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
  309. };
  310. const struct bpf_func_proto bpf_task_storage_delete_proto = {
  311. .func = bpf_task_storage_delete,
  312. .gpl_only = false,
  313. .ret_type = RET_INTEGER,
  314. .arg1_type = ARG_CONST_MAP_PTR,
  315. .arg2_type = ARG_PTR_TO_BTF_ID_OR_NULL,
  316. .arg2_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
  317. };