]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
perf/core: Fix perf_pmu_register() vs. perf_init_event()
authorPeter Zijlstra <peterz@infradead.org>
Mon, 4 Nov 2024 13:39:12 +0000 (14:39 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2025 12:37:37 +0000 (14:37 +0200)
commit68ee6f71a2a9bf9c1a68875162dc490f63d8447a
tree06fb2ea1ad60b6d411ab24e9b90bc05642d5d5a7
parent11e2ae4fe025938c12473a6ff2c4b56aeb6e6d94
perf/core: Fix perf_pmu_register() vs. perf_init_event()

[ Upstream commit 003659fec9f6d8c04738cb74b5384398ae8a7e88 ]

There is a fairly obvious race between perf_init_event() doing
idr_find() and perf_pmu_register() doing idr_alloc() with an
incompletely initialized PMU pointer.

Avoid by doing idr_alloc() on a NULL pointer to register the id, and
swizzling the real struct pmu pointer at the end using idr_replace().

Also making sure to not set struct pmu members after publishing
the struct pmu, duh.

[ introduce idr_cmpxchg() in order to better handle the idr_replace()
  error case -- if it were to return an unexpected pointer, it will
  already have replaced the value and there is no going back. ]

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20241104135517.858805880@infradead.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
kernel/events/core.c