summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorToke Høiland-Jørgensen <toke@redhat.com>2021-10-26 13:00:19 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-02 19:50:56 +0100
commitadb17f828177f1f5811812b85558060a8a08df72 (patch)
treee597f4608259f2046ecac7e11bc34f3e58c803cc /include
parent6f226ffe4458ea3b8c33287cb8c86f87dc198dce (diff)
downloadlinux-adb17f828177f1f5811812b85558060a8a08df72.tar.gz
linux-adb17f828177f1f5811812b85558060a8a08df72.tar.bz2
linux-adb17f828177f1f5811812b85558060a8a08df72.zip
bpf: Fix potential race in tail call compatibility check
commit 54713c85f536048e685258f880bf298a74c3620d upstream. Lorenzo noticed that the code testing for program type compatibility of tail call maps is potentially racy in that two threads could encounter a map with an unset type simultaneously and both return true even though they are inserting incompatible programs. The race window is quite small, but artificially enlarging it by adding a usleep_range() inside the check in bpf_prog_array_compatible() makes it trivial to trigger from userspace with a program that does, essentially: map_fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, 4, 4, 2, 0); pid = fork(); if (pid) { key = 0; value = xdp_fd; } else { key = 1; value = tc_fd; } err = bpf_map_update_elem(map_fd, &key, &value, 0); While the race window is small, it has potentially serious ramifications in that triggering it would allow a BPF program to tail call to a program of a different type. So let's get rid of it by protecting the update with a spinlock. The commit in the Fixes tag is the last commit that touches the code in question. v2: - Use a spinlock instead of an atomic variable and cmpxchg() (Alexei) v3: - Put lock and the members it protects into an embedded 'owner' struct (Daniel) Fixes: 3324b584b6f6 ("ebpf: misc core cleanup") Reported-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20211026110019.363464-1-toke@redhat.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/bpf.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 11da5671d4f0..5c242e047732 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -900,8 +900,11 @@ struct bpf_array_aux {
* stored in the map to make sure that all callers and callees have
* the same prog type and JITed flag.
*/
- enum bpf_prog_type type;
- bool jited;
+ struct {
+ spinlock_t lock;
+ enum bpf_prog_type type;
+ bool jited;
+ } owner;
/* Programs with direct jumps into programs part of this array. */
struct list_head poke_progs;
struct bpf_map *map;