From 4affd79a125ac91e6a53be843ea3960a8fc00cbb Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Sun, 24 Nov 2019 22:58:35 +0800 Subject: regulator: fix use after free issue This is caused by dereferencing 'rdev' after put_device() in the _regulator_get()/_regulator_put() functions. This patch just moves the put_device() down a bit to avoid the issue. Signed-off-by: Wen Yang Cc: Liam Girdwood Cc: Mark Brown Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20191124145835.25999-1-wenyang@linux.alibaba.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5e6c629806e4..c80f3fd9532d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1937,8 +1937,8 @@ struct regulator *_regulator_get(struct device *dev, const char *id, regulator = create_regulator(rdev, dev, id); if (regulator == NULL) { regulator = ERR_PTR(-ENOMEM); - put_device(&rdev->dev); module_put(rdev->owner); + put_device(&rdev->dev); return regulator; } @@ -2059,13 +2059,13 @@ static void _regulator_put(struct regulator *regulator) rdev->open_count--; rdev->exclusive = 0; - put_device(&rdev->dev); regulator_unlock(rdev); kfree_const(regulator->supply_name); kfree(regulator); module_put(rdev->owner); + put_device(&rdev->dev); } /** -- cgit v1.2.3 From a3cde9534ebdafe18a9bbab208df724c57e6c8e8 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Sun, 1 Dec 2019 11:02:50 +0800 Subject: regulator: core: fix regulator_register() error paths to properly release rdev There are several issues with the error handling code of the regulator_register() function: ret = device_register(&rdev->dev); if (ret != 0) { put_device(&rdev->dev); --> rdev released goto unset_supplies; } ... unset_supplies: ... unset_regulator_supplies(rdev); --> use-after-free ... clean: if (dangling_of_gpiod) gpiod_put(config->ena_gpiod); kfree(rdev); --> double free We add a variable to record the failure of device_register() and move put_device() down a bit to avoid the above issues. Fixes: c438b9d01736 ("regulator: core: Move registration of regulator device") Signed-off-by: Wen Yang Cc: Liam Girdwood Cc: Mark Brown Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20191201030250.38074-1-wenyang@linux.alibaba.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c80f3fd9532d..2c3a03cfd381 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4998,6 +4998,7 @@ regulator_register(const struct regulator_desc *regulator_desc, struct regulator_dev *rdev; bool dangling_cfg_gpiod = false; bool dangling_of_gpiod = false; + bool reg_device_fail = false; struct device *dev; int ret, i; @@ -5183,7 +5184,7 @@ regulator_register(const struct regulator_desc *regulator_desc, dev_set_drvdata(&rdev->dev, rdev); ret = device_register(&rdev->dev); if (ret != 0) { - put_device(&rdev->dev); + reg_device_fail = true; goto unset_supplies; } @@ -5213,7 +5214,10 @@ wash: clean: if (dangling_of_gpiod) gpiod_put(config->ena_gpiod); - kfree(rdev); + if (reg_device_fail) + put_device(&rdev->dev); + else + kfree(rdev); kfree(config); rinse: if (dangling_cfg_gpiod) -- cgit v1.2.3 From f3c7f7b636ef5061906aa119eccc2b8dbbaf7199 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 3 Dec 2019 22:48:38 +0100 Subject: regulator: s5m8767: Fix a warning message Axe a duplicated word ("property") in a warning message. Signed-off-by: Christophe JAILLET Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20191203214838.9680-1-christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index bdc07739e9a2..12d6b8d2e97e 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -588,7 +588,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, if (of_property_read_u32(reg_np, "op_mode", &rmode->mode)) { dev_warn(iodev->dev, - "no op_mode property property at %pOF\n", + "no op_mode property at %pOF\n", reg_np); rmode->mode = S5M8767_OPMODE_NORMAL_MODE; -- cgit v1.2.3 From 6d30fc511bec82dd8801b9bb8718cbeea1366ad8 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Mon, 9 Dec 2019 12:52:39 +0000 Subject: regulator: core: avoid unneeded .list_voltage calls Inside machine_constraints_voltage() a loop is in charge of verifying that each of the defined voltages are within the configured constraints and that those constraints are in fact compatible with the available voltages' list. When the registered regulator happens to be defined with a wide range of possible voltages the above O(n) loop can be costly. Moreover since this behaviour is triggered during the registration process, it means also that it can be easily triggered at probe time, slowing down considerably some module loading. On the other side if such wide range of voltage values happens to be also continuous and without discontinuity of any kind, the above potentially cumbersome operation is also useless. For these reasons, avoid such .list_voltage poll loop when regulator is described as 'continuous_voltage_range' as is, indeed, similarly already done inside regulator_is_supported_voltage(). Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20191209125239.46054-1-cristian.marussi@arm.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2c3a03cfd381..2961ac08d1ae 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1198,6 +1198,10 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, return -EINVAL; } + /* no need to loop voltages if range is continuous */ + if (rdev->desc->continuous_voltage_range) + return 0; + /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ for (i = 0; i < count; i++) { int value; -- cgit v1.2.3 From 100a21100bbb2bbc82fc4273e152c96e5c6c5d12 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 10 Dec 2019 11:07:25 +0100 Subject: regulator: max77650: add of_match table We need the of_match table if we want to use the compatible string in the pmic's child node and get the regulator driver loaded automatically. Signed-off-by: Bartosz Golaszewski Link: https://lore.kernel.org/r/20191210100725.11005-1-brgl@bgdev.pl Signed-off-by: Mark Brown --- drivers/regulator/max77650-regulator.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index e57fc9197d62..ac89a412f665 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -386,9 +386,16 @@ static int max77650_regulator_probe(struct platform_device *pdev) return 0; } +static const struct of_device_id max77650_regulator_of_match[] = { + { .compatible = "maxim,max77650-regulator" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77650_regulator_of_match); + static struct platform_driver max77650_regulator_driver = { .driver = { .name = "max77650-regulator", + .of_match_table = max77650_regulator_of_match, }, .probe = max77650_regulator_probe, }; -- cgit v1.2.3 From 62a1923cc8fe095912e6213ed5de27abbf1de77e Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Wed, 11 Dec 2019 23:16:00 +0100 Subject: regulator: rn5t618: fix module aliases platform device aliases were missing, preventing autoloading of module. Fixes: 811b700630ff ("regulator: rn5t618: add driver for Ricoh RN5T618 regulators") Signed-off-by: Andreas Kemnade Link: https://lore.kernel.org/r/20191211221600.29438-1-andreas@kemnade.info Signed-off-by: Mark Brown --- drivers/regulator/rn5t618-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index eb807a059479..aa6e7c5341ce 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c @@ -148,6 +148,7 @@ static struct platform_driver rn5t618_regulator_driver = { module_platform_driver(rn5t618_regulator_driver); +MODULE_ALIAS("platform:rn5t618-regulator"); MODULE_AUTHOR("Beniamino Galvani "); MODULE_DESCRIPTION("RN5T618 regulator driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3