When updating hash maps with BPF_F_LOCK, the special fields were not freed after being replaced. This could cause memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the map gets freed. Fix this by calling 'check_and_free_fields()' after 'copy_map_value_locked()' to properly release the old fields. Fixes: 14a324f6a67e ("bpf: Wire up freeing of referenced kptr") Signed-off-by: Leon Hwang --- kernel/bpf/hashtab.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 3861f28a6be81..fc3c7ede3cd0c 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -1110,6 +1110,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value, copy_map_value_locked(map, htab_elem_value(l_old, key_size), value, false); + check_and_free_fields(htab, l_old); return 0; } /* fall through, grab the bucket lock and lookup again. @@ -1138,6 +1139,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value, copy_map_value_locked(map, htab_elem_value(l_old, key_size), value, false); + check_and_free_fields(htab, l_old); ret = 0; goto err; } -- 2.51.1