Message ID | 20240829025807.2455823-1-jianhui.lee@canonical.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | regulator: mt6359: Fix UBSAN shift-out-of-bounds | expand |
On Thu, Aug 29, 2024 at 10:58:07AM +0800, Jian Hui Lee wrote: > A shift-out-of-bounds will occur as caught by LTP fs:read_all_sys, if > modeset_mask has not been set for MT6359_LDO_LINEAR regulators. > > Example command on MediaTek Genio 1200-EVK: > # cat /sys/devices/platform/soc/10024000.pwrap/10024000.pwrap\:pmic/regulator/regulator.28/opmode > > This patch initializes the member modeset_reg to zero, and checks it > before any further actions. It would be better to fix this by not registering any mode operations for the relevant regulators, that will catch these and any other or future issues.
diff --git a/drivers/regulator/mt6359-regulator.c b/drivers/regulator/mt6359-regulator.c index c8a788858824..24b1dcc5eee8 100644 --- a/drivers/regulator/mt6359-regulator.c +++ b/drivers/regulator/mt6359-regulator.c @@ -88,6 +88,7 @@ struct mt6359_regulator_info { .enable_reg = _enable_reg, \ .enable_mask = BIT(0), \ }, \ + .modeset_reg = 0, \ .status_reg = _status_reg, \ .qi = BIT(0), \ } @@ -270,6 +271,9 @@ static unsigned int mt6359_regulator_get_mode(struct regulator_dev *rdev) struct mt6359_regulator_info *info = rdev_get_drvdata(rdev); int ret, regval; + if (!info->modeset_reg) + return REGULATOR_MODE_NORMAL; + ret = regmap_read(rdev->regmap, info->modeset_reg, ®val); if (ret != 0) { dev_err(&rdev->dev, @@ -303,6 +307,9 @@ static int mt6359_regulator_set_mode(struct regulator_dev *rdev, int ret = 0, val; int curr_mode; + if (!info->modeset_reg) + return -EINVAL; + curr_mode = mt6359_regulator_get_mode(rdev); switch (mode) { case REGULATOR_MODE_FAST:
A shift-out-of-bounds will occur as caught by LTP fs:read_all_sys, if modeset_mask has not been set for MT6359_LDO_LINEAR regulators. Example command on MediaTek Genio 1200-EVK: # cat /sys/devices/platform/soc/10024000.pwrap/10024000.pwrap\:pmic/regulator/regulator.28/opmode This patch initializes the member modeset_reg to zero, and checks it before any further actions. The related log: UBSAN: shift-out-of-bounds in ../drivers/regulator/mt6359-regulator.c:281:9 shift exponent -1 is negative CPU: 1 UID: 0 PID: 4473 Comm: cat Not tainted 6.11.0-rc2-custom #1 Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10 10/01/2022 Call trace: dump_backtrace+0xa0/0x148 show_stack+0x20/0x48 dump_stack_lvl+0x80/0x130 dump_stack+0x18/0x30 __ubsan_handle_shift_out_of_bounds+0x144/0x250 mt6359_regulator_get_mode+0x154/0x160 [mt6359_regulator] opmode_show+0x84/0x150 dev_attr_show+0x28/0xa8 sysfs_kf_seq_show+0x90/0x180 kernfs_seq_show+0x34/0x60 seq_read_iter+0x1f0/0x518 kernfs_fop_read_iter+0x170/0x220 vfs_read+0x288/0x338 ksys_read+0x70/0x120 __arm64_sys_read+0x24/0x48 invoke_syscall+0x70/0x120 el0_svc_common.constprop.0+0x48/0x138 do_el0_svc+0x28/0x58 el0_svc+0x40/0x1a8 el0t_64_sync_handler+0x15c/0x178 el0t_64_sync+0x1a8/0x1b0 ---[ end trace ]--- Fixes: d6208ba87066 ("regulator: mt6359: Remove shift fields from struct mt6359_regulator_info") Suggested-by: Yu-wen Fang <yu-wen.fang@mediatek.com> Signed-off-by: Jian Hui Lee <jianhui.lee@canonical.com> --- drivers/regulator/mt6359-regulator.c | 7 +++++++ 1 file changed, 7 insertions(+)