mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 08:46:46 +00:00
bpf: Fix map leak in HASH_OF_MAPS map
[ Upstream commit1d4e1eab45
] Fix HASH_OF_MAPS bug of not putting inner map pointer on bpf_map_elem_update() operation. This is due to per-cpu extra_elems optimization, which bypassed free_htab_elem() logic doing proper clean ups. Make sure that inner map is put properly in optimized case as well. Fixes:8c290e60fa
("bpf: fix hashmap extra_elems logic") Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Song Liu <songliubraving@fb.com> Link: https://lore.kernel.org/bpf/20200729040913.2815687-1-andriin@fb.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
8091ddc069
commit
e1aa01195b
1 changed files with 9 additions and 3 deletions
|
@ -656,15 +656,20 @@ static void htab_elem_free_rcu(struct rcu_head *head)
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
|
static void htab_put_fd_value(struct bpf_htab *htab, struct htab_elem *l)
|
||||||
{
|
{
|
||||||
struct bpf_map *map = &htab->map;
|
struct bpf_map *map = &htab->map;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
if (map->ops->map_fd_put_ptr) {
|
if (map->ops->map_fd_put_ptr) {
|
||||||
void *ptr = fd_htab_map_get_ptr(map, l);
|
ptr = fd_htab_map_get_ptr(map, l);
|
||||||
|
|
||||||
map->ops->map_fd_put_ptr(ptr);
|
map->ops->map_fd_put_ptr(ptr);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
|
||||||
|
{
|
||||||
|
htab_put_fd_value(htab, l);
|
||||||
|
|
||||||
if (htab_is_prealloc(htab)) {
|
if (htab_is_prealloc(htab)) {
|
||||||
__pcpu_freelist_push(&htab->freelist, &l->fnode);
|
__pcpu_freelist_push(&htab->freelist, &l->fnode);
|
||||||
|
@ -725,6 +730,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
|
||||||
*/
|
*/
|
||||||
pl_new = this_cpu_ptr(htab->extra_elems);
|
pl_new = this_cpu_ptr(htab->extra_elems);
|
||||||
l_new = *pl_new;
|
l_new = *pl_new;
|
||||||
|
htab_put_fd_value(htab, old_elem);
|
||||||
*pl_new = old_elem;
|
*pl_new = old_elem;
|
||||||
} else {
|
} else {
|
||||||
struct pcpu_freelist_node *l;
|
struct pcpu_freelist_node *l;
|
||||||
|
|
Loading…
Reference in a new issue