summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToshiaki Makita <toshiaki.makita1@gmail.com>2019-06-14 17:20:13 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-14 08:11:11 +0200
commit8d09e862103bc61dce7b71ea26eab31356d23d98 (patch)
treec58dbecf3c70af2d9cab1a224df2b6abde47f2be
parentba0afe520ee9c41670c30f9f4ea7669561dff1bb (diff)
bpf, devmap: Fix premature entry free on destroying map
[ Upstream commit d4dd153d551634683fccf8881f606fa9f3dfa1ef ] dev_map_free() waits for flush_needed bitmap to be empty in order to ensure all flush operations have completed before freeing its entries. However the corresponding clear_bit() was called before using the entries, so the entries could be used after free. All access to the entries needs to be done before clearing the bit. It seems commit a5e2da6e9787 ("bpf: netdev is never null in __dev_map_flush") accidentally changed the clear_bit() and memory access order. Note that the problem happens only in __dev_map_flush(), not in dev_map_flush_old(). dev_map_flush_old() is called only after nulling out the corresponding netdev_map entry, so dev_map_free() never frees the entry thus no such race happens there. Fixes: a5e2da6e9787 ("bpf: netdev is never null in __dev_map_flush") Signed-off-by: Toshiaki Makita <toshiaki.makita1@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--kernel/bpf/devmap.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index 2faad033715f..99353ac28cd4 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -291,10 +291,10 @@ void __dev_map_flush(struct bpf_map *map)
if (unlikely(!dev))
continue;
- __clear_bit(bit, bitmap);
-
bq = this_cpu_ptr(dev->bulkq);
bq_xmit_all(dev, bq, XDP_XMIT_FLUSH, true);
+
+ __clear_bit(bit, bitmap);
}
}