diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2019-04-09 17:20:05 -0400 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2019-04-09 20:05:46 -0400 |
commit | 591fe9888d7809d9ee5c828020b6c6ae27c37229 (patch) | |
tree | 7032fc4e23d63b9cd0b301338e1bc49965eb175b /kernel/bpf/arraymap.c | |
parent | be70bcd53de66e86f2726e576307cbdaebd3b1a5 (diff) |
bpf: add program side {rd, wr}only support for maps
This work adds two new map creation flags BPF_F_RDONLY_PROG
and BPF_F_WRONLY_PROG in order to allow for read-only or
write-only BPF maps from a BPF program side.
Today we have BPF_F_RDONLY and BPF_F_WRONLY, but this only
applies to system call side, meaning the BPF program has full
read/write access to the map as usual while bpf(2) calls with
map fd can either only read or write into the map depending
on the flags. BPF_F_RDONLY_PROG and BPF_F_WRONLY_PROG allows
for the exact opposite such that verifier is going to reject
program loads if write into a read-only map or a read into a
write-only map is detected. For read-only map case also some
helpers are forbidden for programs that would alter the map
state such as map deletion, update, etc. As opposed to the two
BPF_F_RDONLY / BPF_F_WRONLY flags, BPF_F_RDONLY_PROG as well
as BPF_F_WRONLY_PROG really do correspond to the map lifetime.
We've enabled this generic map extension to various non-special
maps holding normal user data: array, hash, lru, lpm, local
storage, queue and stack. Further generic map types could be
followed up in future depending on use-case. Main use case
here is to forbid writes into .rodata map values from verifier
side.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r-- | kernel/bpf/arraymap.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 1a6e9861d554..217b10bd9f48 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "map_in_map.h" | 22 | #include "map_in_map.h" |
23 | 23 | ||
24 | #define ARRAY_CREATE_FLAG_MASK \ | 24 | #define ARRAY_CREATE_FLAG_MASK \ |
25 | (BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY) | 25 | (BPF_F_NUMA_NODE | BPF_F_ACCESS_MASK) |
26 | 26 | ||
27 | static void bpf_array_free_percpu(struct bpf_array *array) | 27 | static void bpf_array_free_percpu(struct bpf_array *array) |
28 | { | 28 | { |
@@ -63,6 +63,7 @@ int array_map_alloc_check(union bpf_attr *attr) | |||
63 | if (attr->max_entries == 0 || attr->key_size != 4 || | 63 | if (attr->max_entries == 0 || attr->key_size != 4 || |
64 | attr->value_size == 0 || | 64 | attr->value_size == 0 || |
65 | attr->map_flags & ~ARRAY_CREATE_FLAG_MASK || | 65 | attr->map_flags & ~ARRAY_CREATE_FLAG_MASK || |
66 | !bpf_map_flags_access_ok(attr->map_flags) || | ||
66 | (percpu && numa_node != NUMA_NO_NODE)) | 67 | (percpu && numa_node != NUMA_NO_NODE)) |
67 | return -EINVAL; | 68 | return -EINVAL; |
68 | 69 | ||
@@ -472,6 +473,9 @@ static int fd_array_map_alloc_check(union bpf_attr *attr) | |||
472 | /* only file descriptors can be stored in this type of map */ | 473 | /* only file descriptors can be stored in this type of map */ |
473 | if (attr->value_size != sizeof(u32)) | 474 | if (attr->value_size != sizeof(u32)) |
474 | return -EINVAL; | 475 | return -EINVAL; |
476 | /* Program read-only/write-only not supported for special maps yet. */ | ||
477 | if (attr->map_flags & (BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG)) | ||
478 | return -EINVAL; | ||
475 | return array_map_alloc_check(attr); | 479 | return array_map_alloc_check(attr); |
476 | } | 480 | } |
477 | 481 | ||