Commit 3932bef1 authored by Junhao He's avatar Junhao He
Browse files

perf: hisi: Fix use-after-free when register pmu fails

maillist inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8BOML
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git/commit/?h=for-next/perf&id=b805cafc604bfdb671fae7347a57f51154afa735



--------------------------------

When we fail to register the uncore pmu, the pmu context may not been
allocated. The error handing will call cpuhp_state_remove_instance()
to call uncore pmu offline callback, which migrate the pmu context.
Since that's liable to lead to some kind of use-after-free.

Use cpuhp_state_remove_instance_nocalls() instead of
cpuhp_state_remove_instance() so that the notifiers don't execute after
the PMU device has been failed to register.

Fixes: a0ab25cd ("drivers/perf: hisi: Add support for HiSilicon PA PMU driver")
FIxes: 3bf30882 ("drivers/perf: hisi: Add support for HiSilicon SLLC PMU driver")
Signed-off-by: default avatarJunhao He <hejunhao3@huawei.com>
Link: https://lore.kernel.org/r/20231024113630.13472-1-hejunhao3@huawei.com


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 1abae59a
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -505,7 +505,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
	ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
	if (ret) {
		dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
		cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
		cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
						    &pa_pmu->node);
		return ret;
	}
+2 −2
Original line number Diff line number Diff line
@@ -450,7 +450,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
	ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
	if (ret) {
		dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
		cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
		cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
						    &sllc_pmu->node);
		return ret;
	}