Commit 47363f15 authored by Hou Tao's avatar Hou Tao Committed by Alexei Starovoitov
Browse files

bpf: Free element after unlock in __htab_map_lookup_and_delete_elem()



The freeing of special fields in map value may acquire a spin-lock
(e.g., the freeing of bpf_timer), however, the lookup_and_delete_elem
procedure has already held a raw-spin-lock, which violates the lockdep
rule.

The running context of __htab_map_lookup_and_delete_elem() has already
disabled the migration. Therefore, it is OK to invoke free_htab_elem()
after unlocking the bucket lock.

Fix the potential problem by freeing element after unlocking bucket lock
in __htab_map_lookup_and_delete_elem().

Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20250117101816.2101857-4-houtao@huaweicloud.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 588c6ead
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1663,14 +1663,16 @@ static int __htab_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
		check_and_init_map_value(map, value);
	}
	hlist_nulls_del_rcu(&l->hash_node);
	if (!is_lru_map)
		free_htab_elem(htab, l);

out_unlock:
	htab_unlock_bucket(htab, b, hash, bflags);

	if (is_lru_map && l)
	if (l) {
		if (is_lru_map)
			htab_lru_push_free(htab, l);
		else
			free_htab_elem(htab, l);
	}

	return ret;
}