Skip to content

Commit 1d4e1ea

Browse files
anakryikoborkmann
authored andcommitted
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: 8c290e6 ("bpf: fix hashmap extra_elems logic") Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 5b801df commit 1d4e1ea

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

kernel/bpf/hashtab.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,15 +779,20 @@ static void htab_elem_free_rcu(struct rcu_head *head)
779779
htab_elem_free(htab, l);
780780
}
781781

782-
static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
782+
static void htab_put_fd_value(struct bpf_htab *htab, struct htab_elem *l)
783783
{
784784
struct bpf_map *map = &htab->map;
785+
void *ptr;
785786

786787
if (map->ops->map_fd_put_ptr) {
787-
void *ptr = fd_htab_map_get_ptr(map, l);
788-
788+
ptr = fd_htab_map_get_ptr(map, l);
789789
map->ops->map_fd_put_ptr(ptr);
790790
}
791+
}
792+
793+
static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l)
794+
{
795+
htab_put_fd_value(htab, l);
791796

792797
if (htab_is_prealloc(htab)) {
793798
__pcpu_freelist_push(&htab->freelist, &l->fnode);
@@ -839,6 +844,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
839844
*/
840845
pl_new = this_cpu_ptr(htab->extra_elems);
841846
l_new = *pl_new;
847+
htab_put_fd_value(htab, old_elem);
842848
*pl_new = old_elem;
843849
} else {
844850
struct pcpu_freelist_node *l;

0 commit comments

Comments
 (0)