bpf: Fix map leak in HASH_OF_MAPS map

Conflict: None
Upstream: 1d4e1eab456e1ee92a94987499b211db05f900ea

Backports following upstream commit:
commit 1d4e1eab456e1ee92a94987499b211db05f900ea
Author: Andrii Nakryiko <andriin@fb.com>
Date:   Tue Jul 28 21:09:12 2020 -0700

    bpf: Fix map leak in HASH_OF_MAPS map

    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: 8c290e60fa2a ("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: Kairui Song <kasong@tencent.com>
This commit is contained in:
Kairui Song 2021-12-03 14:48:25 +08:00 committed by kaixuxiakx
parent 4a21bdff34
commit 90bf81d5a4
1 changed files with 9 additions and 3 deletions

View File

@ -644,15 +644,20 @@ static void htab_elem_free_rcu(struct rcu_head *head)
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;
void *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);
}
}
static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
{
htab_put_fd_value(htab, l);
if (htab_is_prealloc(htab)) {
pcpu_freelist_push(&htab->freelist, &l->fnode);
@ -713,6 +718,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
*/
pl_new = this_cpu_ptr(htab->extra_elems);
l_new = *pl_new;
htab_put_fd_value(htab, old_elem);
*pl_new = old_elem;
} else {
struct pcpu_freelist_node *l;