bpf_inode_storage.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2019 Facebook
  4. * Copyright 2020 Google LLC.
  5. */
  6. #include <linux/rculist.h>
  7. #include <linux/list.h>
  8. #include <linux/hash.h>
  9. #include <linux/types.h>
  10. #include <linux/spinlock.h>
  11. #include <linux/bpf.h>
  12. #include <linux/bpf_local_storage.h>
  13. #include <net/sock.h>
  14. #include <uapi/linux/sock_diag.h>
  15. #include <uapi/linux/btf.h>
  16. #include <linux/bpf_lsm.h>
  17. #include <linux/btf_ids.h>
  18. #include <linux/fdtable.h>
  19. #include <linux/rcupdate_trace.h>
  20. DEFINE_BPF_STORAGE_CACHE(inode_cache);
  21. static struct bpf_local_storage __rcu **
  22. inode_storage_ptr(void *owner)
  23. {
  24. struct inode *inode = owner;
  25. struct bpf_storage_blob *bsb;
  26. bsb = bpf_inode(inode);
  27. if (!bsb)
  28. return NULL;
  29. return &bsb->storage;
  30. }
  31. static struct bpf_local_storage_data *inode_storage_lookup(struct inode *inode,
  32. struct bpf_map *map,
  33. bool cacheit_lockit)
  34. {
  35. struct bpf_local_storage *inode_storage;
  36. struct bpf_local_storage_map *smap;
  37. struct bpf_storage_blob *bsb;
  38. bsb = bpf_inode(inode);
  39. if (!bsb)
  40. return NULL;
  41. inode_storage =
  42. rcu_dereference_check(bsb->storage, bpf_rcu_lock_held());
  43. if (!inode_storage)
  44. return NULL;
  45. smap = (struct bpf_local_storage_map *)map;
  46. return bpf_local_storage_lookup(inode_storage, smap, cacheit_lockit);
  47. }
  48. void bpf_inode_storage_free(struct inode *inode)
  49. {
  50. struct bpf_local_storage_elem *selem;
  51. struct bpf_local_storage *local_storage;
  52. bool free_inode_storage = false;
  53. struct bpf_storage_blob *bsb;
  54. struct hlist_node *n;
  55. bsb = bpf_inode(inode);
  56. if (!bsb)
  57. return;
  58. rcu_read_lock();
  59. local_storage = rcu_dereference(bsb->storage);
  60. if (!local_storage) {
  61. rcu_read_unlock();
  62. return;
  63. }
  64. /* Neither the bpf_prog nor the bpf-map's syscall
  65. * could be modifying the local_storage->list now.
  66. * Thus, no elem can be added-to or deleted-from the
  67. * local_storage->list by the bpf_prog or by the bpf-map's syscall.
  68. *
  69. * It is racing with bpf_local_storage_map_free() alone
  70. * when unlinking elem from the local_storage->list and
  71. * the map's bucket->list.
  72. */
  73. raw_spin_lock_bh(&local_storage->lock);
  74. hlist_for_each_entry_safe(selem, n, &local_storage->list, snode) {
  75. /* Always unlink from map before unlinking from
  76. * local_storage.
  77. */
  78. bpf_selem_unlink_map(selem);
  79. free_inode_storage = bpf_selem_unlink_storage_nolock(
  80. local_storage, selem, false, false);
  81. }
  82. raw_spin_unlock_bh(&local_storage->lock);
  83. rcu_read_unlock();
  84. /* free_inoode_storage should always be true as long as
  85. * local_storage->list was non-empty.
  86. */
  87. if (free_inode_storage)
  88. kfree_rcu(local_storage, rcu);
  89. }
  90. static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key)
  91. {
  92. struct bpf_local_storage_data *sdata;
  93. struct file *f;
  94. int fd;
  95. fd = *(int *)key;
  96. f = fget_raw(fd);
  97. if (!f)
  98. return ERR_PTR(-EBADF);
  99. sdata = inode_storage_lookup(f->f_inode, map, true);
  100. fput(f);
  101. return sdata ? sdata->data : NULL;
  102. }
  103. static int bpf_fd_inode_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 file *f;
  108. int fd;
  109. fd = *(int *)key;
  110. f = fget_raw(fd);
  111. if (!f)
  112. return -EBADF;
  113. if (!inode_storage_ptr(f->f_inode)) {
  114. fput(f);
  115. return -EBADF;
  116. }
  117. sdata = bpf_local_storage_update(f->f_inode,
  118. (struct bpf_local_storage_map *)map,
  119. value, map_flags, GFP_ATOMIC);
  120. fput(f);
  121. return PTR_ERR_OR_ZERO(sdata);
  122. }
  123. static int inode_storage_delete(struct inode *inode, struct bpf_map *map)
  124. {
  125. struct bpf_local_storage_data *sdata;
  126. sdata = inode_storage_lookup(inode, map, false);
  127. if (!sdata)
  128. return -ENOENT;
  129. bpf_selem_unlink(SELEM(sdata), true);
  130. return 0;
  131. }
  132. static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
  133. {
  134. struct file *f;
  135. int fd, err;
  136. fd = *(int *)key;
  137. f = fget_raw(fd);
  138. if (!f)
  139. return -EBADF;
  140. err = inode_storage_delete(f->f_inode, map);
  141. fput(f);
  142. return err;
  143. }
  144. /* *gfp_flags* is a hidden argument provided by the verifier */
  145. BPF_CALL_5(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode,
  146. void *, value, u64, flags, gfp_t, gfp_flags)
  147. {
  148. struct bpf_local_storage_data *sdata;
  149. WARN_ON_ONCE(!bpf_rcu_lock_held());
  150. if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE))
  151. return (unsigned long)NULL;
  152. /* explicitly check that the inode_storage_ptr is not
  153. * NULL as inode_storage_lookup returns NULL in this case and
  154. * bpf_local_storage_update expects the owner to have a
  155. * valid storage pointer.
  156. */
  157. if (!inode || !inode_storage_ptr(inode))
  158. return (unsigned long)NULL;
  159. sdata = inode_storage_lookup(inode, map, true);
  160. if (sdata)
  161. return (unsigned long)sdata->data;
  162. /* This helper must only called from where the inode is guaranteed
  163. * to have a refcount and cannot be freed.
  164. */
  165. if (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) {
  166. sdata = bpf_local_storage_update(
  167. inode, (struct bpf_local_storage_map *)map, value,
  168. BPF_NOEXIST, gfp_flags);
  169. return IS_ERR(sdata) ? (unsigned long)NULL :
  170. (unsigned long)sdata->data;
  171. }
  172. return (unsigned long)NULL;
  173. }
  174. BPF_CALL_2(bpf_inode_storage_delete,
  175. struct bpf_map *, map, struct inode *, inode)
  176. {
  177. WARN_ON_ONCE(!bpf_rcu_lock_held());
  178. if (!inode)
  179. return -EINVAL;
  180. /* This helper must only called from where the inode is guaranteed
  181. * to have a refcount and cannot be freed.
  182. */
  183. return inode_storage_delete(inode, map);
  184. }
  185. static int notsupp_get_next_key(struct bpf_map *map, void *key,
  186. void *next_key)
  187. {
  188. return -ENOTSUPP;
  189. }
  190. static struct bpf_map *inode_storage_map_alloc(union bpf_attr *attr)
  191. {
  192. struct bpf_local_storage_map *smap;
  193. smap = bpf_local_storage_map_alloc(attr);
  194. if (IS_ERR(smap))
  195. return ERR_CAST(smap);
  196. smap->cache_idx = bpf_local_storage_cache_idx_get(&inode_cache);
  197. return &smap->map;
  198. }
  199. static void inode_storage_map_free(struct bpf_map *map)
  200. {
  201. struct bpf_local_storage_map *smap;
  202. smap = (struct bpf_local_storage_map *)map;
  203. bpf_local_storage_cache_idx_free(&inode_cache, smap->cache_idx);
  204. bpf_local_storage_map_free(smap, NULL);
  205. }
  206. BTF_ID_LIST_SINGLE(inode_storage_map_btf_ids, struct,
  207. bpf_local_storage_map)
  208. const struct bpf_map_ops inode_storage_map_ops = {
  209. .map_meta_equal = bpf_map_meta_equal,
  210. .map_alloc_check = bpf_local_storage_map_alloc_check,
  211. .map_alloc = inode_storage_map_alloc,
  212. .map_free = inode_storage_map_free,
  213. .map_get_next_key = notsupp_get_next_key,
  214. .map_lookup_elem = bpf_fd_inode_storage_lookup_elem,
  215. .map_update_elem = bpf_fd_inode_storage_update_elem,
  216. .map_delete_elem = bpf_fd_inode_storage_delete_elem,
  217. .map_check_btf = bpf_local_storage_map_check_btf,
  218. .map_btf_id = &inode_storage_map_btf_ids[0],
  219. .map_owner_storage_ptr = inode_storage_ptr,
  220. };
  221. BTF_ID_LIST_SINGLE(bpf_inode_storage_btf_ids, struct, inode)
  222. const struct bpf_func_proto bpf_inode_storage_get_proto = {
  223. .func = bpf_inode_storage_get,
  224. .gpl_only = false,
  225. .ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
  226. .arg1_type = ARG_CONST_MAP_PTR,
  227. .arg2_type = ARG_PTR_TO_BTF_ID,
  228. .arg2_btf_id = &bpf_inode_storage_btf_ids[0],
  229. .arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
  230. .arg4_type = ARG_ANYTHING,
  231. };
  232. const struct bpf_func_proto bpf_inode_storage_delete_proto = {
  233. .func = bpf_inode_storage_delete,
  234. .gpl_only = false,
  235. .ret_type = RET_INTEGER,
  236. .arg1_type = ARG_CONST_MAP_PTR,
  237. .arg2_type = ARG_PTR_TO_BTF_ID,
  238. .arg2_btf_id = &bpf_inode_storage_btf_ids[0],
  239. };