summaryrefslogtreecommitdiff
path: root/kernel/bpf/arraymap.c
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-06-09 21:23:12 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-06-09 21:23:12 -0700
commit1fed2e47fac582e824f77f68722a8a13820e58e2 (patch)
tree703f21d578314c1ee115b1c9a44ee754bdbd90cf /kernel/bpf/arraymap.c
parent140fa23df957b51385aa847986d44ad7f59b0563 (diff)
parent2e7c6cb4d8437a2fe7cd95aac7ca53d7eb05e9f4 (diff)
downloadlinux-1fed2e47fac582e824f77f68722a8a13820e58e2.tar.gz
linux-1fed2e47fac582e824f77f68722a8a13820e58e2.zip
Merge branch 'fix-kptr-dtor-deadlock'
Kumar Kartikeya Dwivedi says: ==================== Fix kptr dtor deadlock Referenced kptr destruction can run from tracing/NMI contexts through bpf_obj_drop() and map value update/delete paths, reaching NMI-unsafe special field teardown and deadlocks. Justin reported the issue and iterated on fixes in [0]-[2], and also confirmed the bpf_obj_drop() reproducer in [3]. This series rejects unsafe obj drops from non-iterator tracing programs, limits map value recycle to NMI-safe field cancellation, and adds focused selftests for the obj_drop(), NMI delete, and recycle teardown cases. See patches for details. [0]: https://lore.kernel.org/bpf/20260505150851.3090688-1-utilityemal77@gmail.com [1]: https://lore.kernel.org/bpf/20260507175453.1140400-1-utilityemal77@gmail.com [2]: https://lore.kernel.org/bpf/20260519011450.1144935-1-utilityemal77@gmail.com [3]: https://lore.kernel.org/bpf/agyG3eQwgmoJwmj2@suesslenovo Changelog: ---------- v2 -> v3 v2: https://lore.kernel.org/bpf/20260609093719.2858096-1-memxor@gmail.com * Replace bpf_obj_cancel_fields() to use bpf_map_free_internal_structs(). (Mykyta) * Fix CI failures. v1 -> v2 v1: https://lore.kernel.org/bpf/20260608144841.1732406-1-memxor@gmail.com * Drop is_tracing_prog_type() fix due to compat breakage, revisit separately. * Rework bpf_obj_drop() fix to additionally reject non-iter tracing progs. ==================== Link: https://patch.msgid.link/20260609202548.3571690-1-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r--kernel/bpf/arraymap.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index e6271a2bf6d6..248b4818178c 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -384,7 +384,7 @@ static long array_map_update_elem(struct bpf_map *map, void *key, void *value,
if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
val = this_cpu_ptr(array->pptrs[index & array->index_mask]);
copy_map_value(map, val, value);
- bpf_obj_free_fields(array->map.record, val);
+ bpf_obj_cancel_fields(map, val);
} else {
val = array->value +
(u64)array->elem_size * (index & array->index_mask);
@@ -392,7 +392,7 @@ static long array_map_update_elem(struct bpf_map *map, void *key, void *value,
copy_map_value_locked(map, val, value, false);
else
copy_map_value(map, val, value);
- bpf_obj_free_fields(array->map.record, val);
+ bpf_obj_cancel_fields(map, val);
}
return 0;
}
@@ -432,14 +432,14 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
cpu = map_flags >> 32;
ptr = per_cpu_ptr(pptr, cpu);
copy_map_value(map, ptr, value);
- bpf_obj_free_fields(array->map.record, ptr);
+ bpf_obj_cancel_fields(map, ptr);
goto unlock;
}
for_each_possible_cpu(cpu) {
ptr = per_cpu_ptr(pptr, cpu);
val = (map_flags & BPF_F_ALL_CPUS) ? value : value + size * cpu;
copy_map_value(map, ptr, val);
- bpf_obj_free_fields(array->map.record, ptr);
+ bpf_obj_cancel_fields(map, ptr);
}
unlock:
rcu_read_unlock();