regulator: Fixes for v6.16

A few driver fixes (the GPIO one being potentially nasty, though it has
 been there for a while without anyone reporting it), and one core fix
 for the rarely used combination of coupled regulators and unbinding.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmhn7SYACgkQJNaLcl1U
 h9Dxdgf/VP9GpJzVC+7m4PhUB/TidvtqH+vVTgR71npy+iC9BKh2BeI6KUJPmMGE
 eqoeGNU3el11pysWl+qSTo7W5VR5TBtblgAMfy1Z33Y1ThVtpR1VvQSjkYDL9alR
 BCvy1pwUjzXiJYV5O4hJZIiOhmHOxANKWehDM2wQC3WJW9AYr8ZinMZtTxCItJa2
 gVbx+EeAC2ot0PdEK/atknn/P0rIXSbquSiZ9Vhag4sM5VMA34Iy3Zml5sKdUDZL
 Rh65qCndId6FQ4b2oi12JPDRNs2RcRzK+UXlTqAFxxKQmwMIE9M+YlsxixUm7KVo
 lrdxwP5+JpwE4KQb369CrlOG20dknA==
 =+Ku3
 -----END PGP SIGNATURE-----

Merge tag 'regulator-fix-v6.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "A few driver fixes (the GPIO one being potentially nasty, though it
  has been there for a while without anyone reporting it), and one core
  fix for the rarely used combination of coupled regulators and
  unbinding"

* tag 'regulator-fix-v6.16-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: gpio: Fix the out-of-bounds access to drvdata::gpiods
  regulator: mp886x: Fix ID table driver_data
  regulator: sy8824x: Fix ID table driver_data
  regulator: tps65219: Fix devm_kmalloc size allocation
  regulator: core: fix NULL dereference on unbind due to stale coupling data
This commit is contained in:
Linus Torvalds 2025-07-04 10:14:49 -07:00
commit 4b02ed4ab7
5 changed files with 25 additions and 20 deletions

View File

@ -5639,6 +5639,7 @@ static void regulator_remove_coupling(struct regulator_dev *rdev)
ERR_PTR(err));
}
rdev->coupling_desc.n_coupled = 0;
kfree(rdev->coupling_desc.coupled_rdevs);
rdev->coupling_desc.coupled_rdevs = NULL;
}

View File

@ -260,8 +260,10 @@ static int gpio_regulator_probe(struct platform_device *pdev)
return -ENOMEM;
}
drvdata->gpiods = devm_kzalloc(dev, sizeof(struct gpio_desc *),
GFP_KERNEL);
drvdata->gpiods = devm_kcalloc(dev, config->ngpios,
sizeof(struct gpio_desc *), GFP_KERNEL);
if (!drvdata->gpiods)
return -ENOMEM;
if (config->input_supply) {
drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
@ -274,8 +276,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
}
}
if (!drvdata->gpiods)
return -ENOMEM;
for (i = 0; i < config->ngpios; i++) {
drvdata->gpiods[i] = devm_gpiod_get_index(dev,
NULL,

View File

@ -348,7 +348,8 @@ static const struct of_device_id mp886x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
static const struct i2c_device_id mp886x_id[] = {
{ "mp886x", (kernel_ulong_t)&mp8869_ci },
{ "mp8867", (kernel_ulong_t)&mp8867_ci },
{ "mp8869", (kernel_ulong_t)&mp8869_ci },
{ },
};
MODULE_DEVICE_TABLE(i2c, mp886x_id);

View File

@ -213,7 +213,10 @@ static const struct of_device_id sy8824_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
static const struct i2c_device_id sy8824_id[] = {
{ "sy8824", (kernel_ulong_t)&sy8824c_cfg },
{ "sy8824c", (kernel_ulong_t)&sy8824c_cfg },
{ "sy8824e", (kernel_ulong_t)&sy8824e_cfg },
{ "sy20276", (kernel_ulong_t)&sy20276_cfg },
{ "sy20278", (kernel_ulong_t)&sy20278_cfg },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8824_id);

View File

@ -436,46 +436,46 @@ static int tps65219_regulator_probe(struct platform_device *pdev)
pmic->rdesc[i].name);
}
irq_data = devm_kmalloc(tps->dev, pmic->common_irq_size, GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
for (i = 0; i < pmic->common_irq_size; ++i) {
irq_type = &pmic->common_irq_types[i];
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0)
return -EINVAL;
irq_data[i].dev = tps->dev;
irq_data[i].type = irq_type;
irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
irq_data->dev = tps->dev;
irq_data->type = irq_type;
error = devm_request_threaded_irq(tps->dev, irq, NULL,
tps65219_regulator_irq_handler,
IRQF_ONESHOT,
irq_type->irq_name,
&irq_data[i]);
irq_data);
if (error)
return dev_err_probe(tps->dev, PTR_ERR(rdev),
"Failed to request %s IRQ %d: %d\n",
irq_type->irq_name, irq, error);
}
irq_data = devm_kmalloc(tps->dev, pmic->dev_irq_size, GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
for (i = 0; i < pmic->dev_irq_size; ++i) {
irq_type = &pmic->irq_types[i];
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0)
return -EINVAL;
irq_data[i].dev = tps->dev;
irq_data[i].type = irq_type;
irq_data = devm_kmalloc(tps->dev, sizeof(*irq_data), GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
irq_data->dev = tps->dev;
irq_data->type = irq_type;
error = devm_request_threaded_irq(tps->dev, irq, NULL,
tps65219_regulator_irq_handler,
IRQF_ONESHOT,
irq_type->irq_name,
&irq_data[i]);
irq_data);
if (error)
return dev_err_probe(tps->dev, PTR_ERR(rdev),
"Failed to request %s IRQ %d: %d\n",