History

bpf: Centralize permissions checks for all BPF map types

This allows to do more centralized decisions later on, and generally makes it very explicit which maps are privileged and which are not (e.g., LRU_HASH and LRU_PERCPU_HASH, which are privileged HASH variants, as opposed to unprivileged HASH and HASH_PERCPU; now this is explicit and easy to verify).

Andrii Nakryiko committed 3 years ago

Commit 6c3eba11 parent 22db41214 files · +52 −44Browse files

Unified · Split

14 files
  1. kernel/bpf/bloom_filter.c +0 −3
  2. kernel/bpf/bpf_local_storage.c +0 −3
  3. kernel/bpf/bpf_struct_ops.c +0 −3
  4. kernel/bpf/cpumap.c +0 −4
  5. kernel/bpf/devmap.c +0 −3
  6. kernel/bpf/hashtab.c +0 −6
  7. kernel/bpf/lpm_trie.c +0 −3
  8. kernel/bpf/queue_stack_maps.c +0 −4
  9. kernel/bpf/reuseport_array.c +0 −3
  10. kernel/bpf/stackmap.c +0 −3
  11. kernel/bpf/syscall.c +47 −0
  12. net/core/sock_map.c +0 −4
  13. net/xdp/xskmap.c +0 −4
  14. tools/testing/selftests/bpf/prog_tests/unpriv_bpf_disabled.c +5 −1
kernel/bpf/bloom_filter.c+0−3
@@ -86,9 +86,6 @@ static struct bpf_map *bloom_map_alloc(union bpf_attr *attr) · 85 unmodified lines
8686 int numa_node = bpf_map_attr_numa_node(attr);
8787 struct bpf_bloom_filter *bloom;
8888
89− if (!bpf_capable())
90− return ERR_PTR(-EPERM);
91−
9289 if (attr->key_size != 0 || attr->value_size == 0 ||
9390 attr->max_entries == 0 ||
9491 attr->map_flags & ~BLOOM_CREATE_FLAG_MASK ||
kernel/bpf/bpf_local_storage.c+0−3
@@ -723,9 +723,6 @@ int bpf_local_storage_map_alloc_check(union bpf_attr *attr) · 722 unmodified lines
723723 !attr->btf_key_type_id || !attr->btf_value_type_id)
724724 return -EINVAL;
725725
726− if (!bpf_capable())
727− return -EPERM;
728−
729726 if (attr->value_size > BPF_LOCAL_STORAGE_MAX_VALUE_SIZE)
730727 return -E2BIG;
731728
kernel/bpf/bpf_struct_ops.c+0−3
@@ -655,9 +655,6 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr) · 654 unmodified lines
655655 const struct btf_type *t, *vt;
656656 struct bpf_map *map;
657657
658− if (!bpf_capable())
659− return ERR_PTR(-EPERM);
660−
661658 st_ops = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
662659 if (!st_ops)
663660 return ERR_PTR(-ENOTSUPP);
kernel/bpf/cpumap.c+0−4
@@ -28,7 +28,6 @@ · 27 unmodified lines
2828 #include <linux/sched.h>
2929 #include <linux/workqueue.h>
3030 #include <linux/kthread.h>
31−#include <linux/capability.h>
3231 #include <trace/events/xdp.h>
3332 #include <linux/btf_ids.h>
3433
@@ -89,9 +88,6 @@ static struct bpf_map *cpu_map_alloc(union bpf_attr *attr) · 54 unmodified lines
8988 u32 value_size = attr->value_size;
9089 struct bpf_cpu_map *cmap;
9190
92− if (!bpf_capable())
93− return ERR_PTR(-EPERM);
94−
9591 /* check sanity of attributes */
9692 if (attr->max_entries == 0 || attr->key_size != 4 ||
9793 (value_size != offsetofend(struct bpf_cpumap_val, qsize) &&
kernel/bpf/devmap.c+0−3
@@ -160,9 +160,6 @@ static struct bpf_map *dev_map_alloc(union bpf_attr *attr) · 159 unmodified lines
160160 struct bpf_dtab *dtab;
161161 int err;
162162
163− if (!capable(CAP_NET_ADMIN))
164− return ERR_PTR(-EPERM);
165−
166163 dtab = bpf_map_area_alloc(sizeof(*dtab), NUMA_NO_NODE);
167164 if (!dtab)
168165 return ERR_PTR(-ENOMEM);
kernel/bpf/hashtab.c+0−6
@@ -422,12 +422,6 @@ static int htab_map_alloc_check(union bpf_attr *attr) · 421 unmodified lines
422422 BUILD_BUG_ON(offsetof(struct htab_elem, fnode.next) !=
423423 offsetof(struct htab_elem, hash_node.pprev));
424424
425− if (lru && !bpf_capable())
426− /* LRU implementation is much complicated than other
427− * maps. Hence, limit to CAP_BPF.
428− */
429− return -EPERM;
430−
431425 if (zero_seed && !capable(CAP_SYS_ADMIN))
432426 /* Guard against local DoS, and discourage production use. */
433427 return -EPERM;
kernel/bpf/lpm_trie.c+0−3
@@ -544,9 +544,6 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) · 543 unmodified lines
544544 {
545545 struct lpm_trie *trie;
546546
547− if (!bpf_capable())
548− return ERR_PTR(-EPERM);
549−
550547 /* check sanity of attributes */
551548 if (attr->max_entries == 0 ||
552549 !(attr->map_flags & BPF_F_NO_PREALLOC) ||
kernel/bpf/queue_stack_maps.c+0−4
@@ -7,7 +7,6 @@ · 6 unmodified lines
77 #include <linux/bpf.h>
88 #include <linux/list.h>
99 #include <linux/slab.h>
10−#include <linux/capability.h>
1110 #include <linux/btf_ids.h>
1211 #include "percpu_freelist.h"
1312
@@ -46,9 +45,6 @@ static bool queue_stack_map_is_full(struct bpf_queue_stack *qs) · 32 unmodified lines
4645 /* Called from syscall */
4746 static int queue_stack_map_alloc_check(union bpf_attr *attr)
4847 {
49− if (!bpf_capable())
50− return -EPERM;
51−
5248 /* check sanity of attributes */
5349 if (attr->max_entries == 0 || attr->key_size != 0 ||
5450 attr->value_size == 0 ||
kernel/bpf/reuseport_array.c+0−3
@@ -151,9 +151,6 @@ static struct bpf_map *reuseport_array_alloc(union bpf_attr *attr) · 150 unmodified lines
151151 int numa_node = bpf_map_attr_numa_node(attr);
152152 struct reuseport_array *array;
153153
154− if (!bpf_capable())
155− return ERR_PTR(-EPERM);
156−
157154 /* allocate all map elements and zero-initialize them */
158155 array = bpf_map_area_alloc(struct_size(array, ptrs, attr->max_entries), numa_node);
159156 if (!array)
kernel/bpf/stackmap.c+0−3
@@ -74,9 +74,6 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) · 73 unmodified lines
7474 u64 cost, n_buckets;
7575 int err;
7676
77− if (!bpf_capable())
78− return ERR_PTR(-EPERM);
79−
8077 if (attr->map_flags & ~STACK_CREATE_FLAG_MASK)
8178 return ERR_PTR(-EINVAL);
8279
kernel/bpf/syscall.c+47−0
@@ -1156,6 +1156,53 @@ static int map_create(union bpf_attr *attr) · 1155 unmodified lines
11561156 if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
11571157 return -EPERM;
11581158
1159+ /* check privileged map type permissions */
1160+ switch (map_type) {
1161+ case BPF_MAP_TYPE_ARRAY:
1162+ case BPF_MAP_TYPE_PERCPU_ARRAY:
1163+ case BPF_MAP_TYPE_PROG_ARRAY:
1164+ case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
1165+ case BPF_MAP_TYPE_CGROUP_ARRAY:
1166+ case BPF_MAP_TYPE_ARRAY_OF_MAPS:
1167+ case BPF_MAP_TYPE_HASH:
1168+ case BPF_MAP_TYPE_PERCPU_HASH:
1169+ case BPF_MAP_TYPE_HASH_OF_MAPS:
1170+ case BPF_MAP_TYPE_RINGBUF:
1171+ case BPF_MAP_TYPE_USER_RINGBUF:
1172+ case BPF_MAP_TYPE_CGROUP_STORAGE:
1173+ case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE:
1174+ /* unprivileged */
1175+ break;
1176+ case BPF_MAP_TYPE_SK_STORAGE:
1177+ case BPF_MAP_TYPE_INODE_STORAGE:
1178+ case BPF_MAP_TYPE_TASK_STORAGE:
1179+ case BPF_MAP_TYPE_CGRP_STORAGE:
1180+ case BPF_MAP_TYPE_BLOOM_FILTER:
1181+ case BPF_MAP_TYPE_LPM_TRIE:
1182+ case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:
1183+ case BPF_MAP_TYPE_STACK_TRACE:
1184+ case BPF_MAP_TYPE_QUEUE:
1185+ case BPF_MAP_TYPE_STACK:
1186+ case BPF_MAP_TYPE_LRU_HASH:
1187+ case BPF_MAP_TYPE_LRU_PERCPU_HASH:
1188+ case BPF_MAP_TYPE_STRUCT_OPS:
1189+ case BPF_MAP_TYPE_CPUMAP:
1190+ if (!bpf_capable())
1191+ return -EPERM;
1192+ break;
1193+ case BPF_MAP_TYPE_SOCKMAP:
1194+ case BPF_MAP_TYPE_SOCKHASH:
1195+ case BPF_MAP_TYPE_DEVMAP:
1196+ case BPF_MAP_TYPE_DEVMAP_HASH:
1197+ case BPF_MAP_TYPE_XSKMAP:
1198+ if (!capable(CAP_NET_ADMIN))
1199+ return -EPERM;
1200+ break;
1201+ default:
1202+ WARN(1, "unsupported map type %d", map_type);
1203+ return -EPERM;
1204+ }
1205+
11591206 map = ops->map_alloc(attr);
11601207 if (IS_ERR(map))
11611208 return PTR_ERR(map);
net/core/sock_map.c+0−4
@@ -32,8 +32,6 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr) · 31 unmodified lines
3232 {
3333 struct bpf_stab *stab;
3434
35− if (!capable(CAP_NET_ADMIN))
36− return ERR_PTR(-EPERM);
3735 if (attr->max_entries == 0 ||
3836 attr->key_size != 4 ||
3937 (attr->value_size != sizeof(u32) &&
@@ -1085,8 +1083,6 @@ static struct bpf_map *sock_hash_alloc(union bpf_attr *attr) · 1045 unmodified lines
10851083 struct bpf_shtab *htab;
10861084 int i, err;
10871085
1088− if (!capable(CAP_NET_ADMIN))
1089− return ERR_PTR(-EPERM);
10901086 if (attr->max_entries == 0 ||
10911087 attr->key_size == 0 ||
10921088 (attr->value_size != sizeof(u32) &&
net/xdp/xskmap.c+0−4
@@ -5,7 +5,6 @@ · 4 unmodified lines
55
66 #include <linux/bpf.h>
77 #include <linux/filter.h>
8−#include <linux/capability.h>
98 #include <net/xdp_sock.h>
109 #include <linux/slab.h>
1110 #include <linux/sched.h>
@@ -68,9 +67,6 @@ static struct bpf_map *xsk_map_alloc(union bpf_attr *attr) · 56 unmodified lines
6867 int numa_node;
6968 u64 size;
7069
71− if (!capable(CAP_NET_ADMIN))
72− return ERR_PTR(-EPERM);
73−
7470 if (attr->max_entries == 0 || attr->key_size != 4 ||
7571 attr->value_size != 4 ||
7672 attr->map_flags & ~(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY))
tools/testing/selftests/bpf/prog_tests/unpriv_bpf_disabled.c+5−1
@@ -171,7 +171,11 @@ static void test_unpriv_bpf_disabled_negative(struct test_unpriv_bpf_disabled *s · 170 unmodified lines
171171 prog_insns, prog_insn_cnt, &load_opts),
172172 -EPERM, "prog_load_fails");
173173
174− for (i = BPF_MAP_TYPE_HASH; i <= BPF_MAP_TYPE_BLOOM_FILTER; i++)
174+ /* some map types require particular correct parameters which could be
175+ * sanity-checked before enforcing -EPERM, so only validate that
176+ * the simple ARRAY and HASH maps are failing with -EPERM
177+ */
178+ for (i = BPF_MAP_TYPE_HASH; i <= BPF_MAP_TYPE_ARRAY; i++)
175179 ASSERT_EQ(bpf_map_create(i, NULL, sizeof(int), sizeof(int), 1, NULL),
176180 -EPERM, "map_create_fails");
177181