[PATCH] platform/x86: ISST: Fix perf level allocation error handling

Chuyi Zhou posted 1 patch 3 days, 21 hours ago
drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
[PATCH] platform/x86: ISST: Fix perf level allocation error handling
Posted by Chuyi Zhou 3 days, 21 hours ago
sst_add_perf_profiles() allocates the per-level MMIO offset array used by
the SST performance profile IOCTL handlers. If the allocation fails, the
function returns success and sst_main() ignores its return value.

This leaves the power domain registered with perf_levels set to NULL. A
subsequent performance profile IOCTL dereferences perf_levels while
computing an MMIO address, resulting in a NULL pointer dereference.

Return -ENOMEM when the allocation fails and propagate the error through
sst_main() so tpmi_sst_dev_add() discards the incomplete power domain.

Fixes: 0ab147bb840f ("platform/x86: ISST: Parse SST MMIO and update instance")
Signed-off-by: Chuyi Zhou <zhouchuyi@bytedance.com>
---
 drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
index 24334ae70d82..5dc85f448be4 100644
--- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
+++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
@@ -337,7 +337,7 @@ static int sst_add_perf_profiles(struct auxiliary_device *auxdev,
 
 	pd_info->perf_levels = devm_kcalloc(dev, levels, sizeof(struct perf_level), GFP_KERNEL);
 	if (!pd_info->perf_levels)
-		return 0;
+		return -ENOMEM;
 
 	pd_info->ratio_unit = pd_info->pp_header.ratio_unit;
 	pd_info->avx_levels = SST_MAX_AVX_LEVELS;
@@ -400,9 +400,7 @@ static int sst_main(struct auxiliary_device *auxdev, struct tpmi_per_power_domai
 		mask <<= 1;
 	}
 	pd_info->max_level = levels;
-	sst_add_perf_profiles(auxdev, pd_info, levels + 1);
-
-	return 0;
+	return sst_add_perf_profiles(auxdev, pd_info, levels + 1);
 }
 
 static u8 isst_instance_count(struct tpmi_sst_struct *sst_inst)
-- 
2.20.1