[PATCH] firmware: arm_scpi: Add check for dvfs_info.opp_count

Luo Qiu posted 1 patch 3 weeks, 2 days ago
drivers/firmware/arm_scpi.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH] firmware: arm_scpi: Add check for dvfs_info.opp_count
Posted by Luo Qiu 3 weeks, 2 days ago
Fix a kernel crash when dvfs_info.opp_count is zero.

dvfs_info.opp_count may be zero on some platforms during the reboot
test, and the kernel will crash after dereferencing the pointer to
kcalloc(info->count, sizeof(*opp), GFP_KERNEL).

```console
[    9.724138] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
[    9.738420] Mem abort info:
[    9.741223]   ESR = 0x96000004
[    9.744264]   Exception class = DABT (current EL), IL = 32 bits
[    9.750172]   SET = 0, FnV = 0
[    9.753214]   EA = 0, S1PTW = 0
[    9.756342] Data abort info:
[    9.759209]   ISV = 0, ISS = 0x00000004
[    9.763037]   CM = 0, WnR = 0
[    9.765992] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000faefa08c
[    9.772596] [0000000000000028] pgd=0000000000000000
[    9.777465] Internal error: Oops: 96000004 [#1] SMP
[    9.779210] scpi-hwmon: probe of PHYT000D:00 failed with error -110
[    9.782329] Modules linked in: snd_hda_codec phytium_power snd_hda_core snd_pcm clk_scpi(+) optee tee scpi_cpufreq phytium_ec phytium_mailbox scpi_hwmon arm_scpi snd_timer snd soundcore gpio_phytium_platform gpio_phytium_core ip_tables ext4 mbcache jbd2 sd_mod ahci libahci libata phytium_sdci mmc_core rtc_ds1307 i2c_designware_platform i2c_designware_core
[    9.820002] Process systemd-udevd (pid: 1701, stack limit = 0x00000000aaede86c)
[    9.827295] CPU: 2 PID: 1701 Comm: systemd-udevd Not tainted 4.19.90+ #1
[    9.836930] Hardware name: PHYTIUM LTD Phytium FT2000/4/Phytium FT2000/4, BIOS
[    9.844309] pstate: 60000005 (nZCv daif -PAN -UAO)
[    9.849090] pc : scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi]
[    9.854650] lr : clk_register+0x438/0x720
[    9.858644] sp : ffff00000e7eb7e0
[    9.861944] x29: ffff00000e7eb7e0 x28: ffff801f8ab2e580
[    9.867241] x27: ffff801f82198698 x26: ffff801f821eb810
[    9.872537] x25: 0000000000000000 x24: 00000000006080c0
[    9.877833] x23: ffff801f8ab2e588 x22: 0000000000000000
[    9.883129] x21: 0000000000000000 x20: ffff00000987e000
[    9.888426] x19: ffff801f8ab2e600 x18: 0000ffffe4d3e9b0
[    9.893722] x17: 0000000000000000 x16: ffff801f8b011f00
[    9.899018] x15: 00000000000059a4 x14: 0000ffffb89a6a94
[    9.904317] x13: 0000000000000000 x12: ffffffffffffffd0
[    9.904318] x11: 0000000000000000 x10: 0000000000000b80
[    9.904320] x9 : ffff00000e7eb490 x8 : ffff801f8b012ae0
[    9.904321] x7 : 0000000aaab119bb x6 : 0000000000000000
[    9.904322] x5 : 0000000000000000 x4 : ffff801f8a428ce0
[    9.904324] x3 : d855a1d4f736cb00 x2 : 0000000000000003
[    9.904325] x1 : 0000000000000010 x0 : 0000000000000018
[    9.904326] Call trace:
[    9.904330]  scpi_dvfs_recalc_rate+0x40/0x58 [clk_scpi]
[    9.904332]  devm_clk_hw_register+0x50/0xa0
[    9.904334]  scpi_clk_ops_init.isra.2+0xa0/0x138 [clk_scpi]
[    9.904336]  scpi_clocks_probe+0x528/0x70c [clk_scpi]
[    9.904339]  platform_drv_probe+0x58/0xa8
[    9.904342]  really_probe+0x260/0x3d0
[    9.904344]  driver_probe_device+0x12c/0x148
[    9.904346]  device_driver_attach+0x74/0x98
[    9.904348]  __driver_attach+0xb4/0xe8
[    9.904350]  bus_for_each_dev+0x88/0xe0
[    9.904351]  driver_attach+0x30/0x40
[    9.904353]  bus_add_driver+0x178/0x2b0
[    9.904354]  driver_register+0x64/0x118
[    9.904355]  __platform_driver_register+0x54/0x60
[    9.904357]  scpi_clocks_driver_init+0x24/0x1000 [clk_scpi]
[    9.904360]  do_one_initcall+0x54/0x220
[    9.904363]  do_init_module+0x54/0x1c8
[    9.904364]  load_module+0x14a4/0x1668
[    9.904366]  __se_sys_finit_module+0xf8/0x110
[    9.904367]  __arm64_sys_finit_module+0x24/0x30
[    9.904370]  el0_svc_common+0x78/0x170
[    9.904371]  el0_svc_handler+0x38/0x78
[    9.904373]  el0_svc+0x8/0x340
[    9.904375] Code: 937d7c00 a94153f3 a8c27bfd f9400421 (b8606820)
[    9.904380] ---[ end trace 06feb22469d89fa8 ]---
[    9.904381] Kernel panic - not syncing: Fatal exception
[    9.904383] SMP: stopping secondary CPUs
[    9.904387] Kernel Offset: disabled
[    9.904389] CPU features: 0x10,a0002008
[    9.904389] Memory Limit: none
[   10.069666] ---[ end Kernel panic - not syncing: Fatal exception ]---
```

Fixes: 8cb7cf56c9fe ("firmware: add support for ARM System Control and Power Interface(SCPI) protocol")

Signed-off-by: Luo Qiu <luoqiu@kylinsec.com.cn>
---
 drivers/firmware/arm_scpi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 94a6b4e667de1..8e3f4cea6a919 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -630,6 +630,9 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
 	if (ret)
 		return ERR_PTR(ret);
 
+	if (unlikely(buf.opp_count == 0))
+		return ERR_PTR(-ENOENT);
+
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return ERR_PTR(-ENOMEM);
-- 
2.45.2