Skip to content

Commit f8cd222

Browse files
committed
iio:adc:ina2xx Fix timestamp alignment issue.
One of a class of bugs pointed out by Lars in a recent review. iio_push_to_buffers_with_timestamp assumes the buffer used is aligned to the size of the timestamp (8 bytes). This is not guaranteed in this driver which uses a 32 byte array of smaller elements on the stack. As Lars also noted this anti pattern can involve a leak of data to userspace and that indeed can happen here. We close both issues by moving to a suitable structure in the iio_priv() data with alignment explicitly requested. This data is allocated with kzalloc so no data can leak apart from previous readings. The explicit alignment isn't technically needed here, but it reduced fragility and avoids cut and paste into drivers where it will be needed. If we want this in older stables will need manual backport due to driver reworks. Fixes: c43a102 ("iio: ina2xx: add support for TI INA2xx Power Monitors") Reported-by: Lars-Peter Clausen <lars@metafoo.de> Cc: Stefan Brüns <stefan.bruens@rwth-aachen.de> Cc: Marc Titinger <mtitinger@baylibre.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: <Stable@vger.kernel.org>
1 parent a661b57 commit f8cd222

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/iio/adc/ina2xx-adc.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ struct ina2xx_chip_info {
146146
int range_vbus; /* Bus voltage maximum in V */
147147
int pga_gain_vshunt; /* Shunt voltage PGA gain */
148148
bool allow_async_readout;
149+
/* data buffer needs space for channel data and timestamp */
150+
struct {
151+
u16 chan[4];
152+
u64 ts __aligned(8);
153+
} scan;
149154
};
150155

151156
static const struct ina2xx_config ina2xx_config[] = {
@@ -738,8 +743,6 @@ static int ina2xx_conversion_ready(struct iio_dev *indio_dev)
738743
static int ina2xx_work_buffer(struct iio_dev *indio_dev)
739744
{
740745
struct ina2xx_chip_info *chip = iio_priv(indio_dev);
741-
/* data buffer needs space for channel data and timestap */
742-
unsigned short data[4 + sizeof(s64)/sizeof(short)];
743746
int bit, ret, i = 0;
744747
s64 time;
745748

@@ -758,10 +761,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev)
758761
if (ret < 0)
759762
return ret;
760763

761-
data[i++] = val;
764+
chip->scan.chan[i++] = val;
762765
}
763766

764-
iio_push_to_buffers_with_timestamp(indio_dev, data, time);
767+
iio_push_to_buffers_with_timestamp(indio_dev, &chip->scan, time);
765768

766769
return 0;
767770
};

0 commit comments

Comments
 (0)