| From 36a44e05cd807a54e5ffad4b96d0d67f68ad8576 Mon Sep 17 00:00:00 2001 |
| From: David Lechner <dlechner@baylibre.com> |
| Date: Wed, 27 Nov 2024 14:01:53 -0600 |
| Subject: iio: adc: ad7173: fix using shared static info struct |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: David Lechner <dlechner@baylibre.com> |
| |
| commit 36a44e05cd807a54e5ffad4b96d0d67f68ad8576 upstream. |
| |
| Fix a possible race condition during driver probe in the ad7173 driver |
| due to using a shared static info struct. If more that one instance of |
| the driver is probed at the same time, some of the info could be |
| overwritten by the other instance, leading to incorrect operation. |
| |
| To fix this, make the static info struct const so that it is read-only |
| and make a copy of the info struct for each instance of the driver that |
| can be modified. |
| |
| Reported-by: Uwe Kleine-Kรถnig <u.kleine-koenig@baylibre.com> |
| Fixes: 76a1e6a42802 ("iio: adc: ad7173: add AD7173 driver") |
| Signed-off-by: David Lechner <dlechner@baylibre.com> |
| Tested-by: Guillaume Ranquet <granquet@baylibre.com> |
| Link: https://patch.msgid.link/20241127-iio-adc-ad7313-fix-non-const-info-struct-v2-1-b6d7022b7466@baylibre.com |
| Cc: <Stable@vger.kernel.org> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/iio/adc/ad7173.c | 10 ++++++---- |
| 1 file changed, 6 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/iio/adc/ad7173.c |
| +++ b/drivers/iio/adc/ad7173.c |
| @@ -198,6 +198,7 @@ struct ad7173_channel { |
| |
| struct ad7173_state { |
| struct ad_sigma_delta sd; |
| + struct ad_sigma_delta_info sigma_delta_info; |
| const struct ad7173_device_info *info; |
| struct ad7173_channel *channels; |
| struct regulator_bulk_data regulators[3]; |
| @@ -733,7 +734,7 @@ static int ad7173_disable_one(struct ad_ |
| return ad_sd_write_reg(sd, AD7173_REG_CH(chan), 2, 0); |
| } |
| |
| -static struct ad_sigma_delta_info ad7173_sigma_delta_info = { |
| +static const struct ad_sigma_delta_info ad7173_sigma_delta_info = { |
| .set_channel = ad7173_set_channel, |
| .append_status = ad7173_append_status, |
| .disable_all = ad7173_disable_all, |
| @@ -1371,7 +1372,7 @@ static int ad7173_fw_parse_device_config |
| if (ret < 0) |
| return dev_err_probe(dev, ret, "Interrupt 'rdy' is required\n"); |
| |
| - ad7173_sigma_delta_info.irq_line = ret; |
| + st->sigma_delta_info.irq_line = ret; |
| |
| return ad7173_fw_parse_channel_config(indio_dev); |
| } |
| @@ -1404,8 +1405,9 @@ static int ad7173_probe(struct spi_devic |
| spi->mode = SPI_MODE_3; |
| spi_setup(spi); |
| |
| - ad7173_sigma_delta_info.num_slots = st->info->num_configs; |
| - ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7173_sigma_delta_info); |
| + st->sigma_delta_info = ad7173_sigma_delta_info; |
| + st->sigma_delta_info.num_slots = st->info->num_configs; |
| + ret = ad_sd_init(&st->sd, indio_dev, spi, &st->sigma_delta_info); |
| if (ret) |
| return ret; |
| |