Skip to content

Commit 5236288

Browse files
committed
iio:light:max44000 Fix timestamp alignment and prevent data leak.
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 16 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(). This data is allocated with kzalloc so no data can leak appart from previous readings. It is necessary to force the alignment of ts to avoid the padding on x86_32 being different from 64 bit platorms (it alows for 4 bytes aligned 8 byte types. Fixes: 06ad7ea ("max44000: Initial triggered buffer support") Reported-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: <Stable@vger.kernel.org>
1 parent eb1a148 commit 5236288

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

drivers/iio/light/max44000.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
struct max44000_data {
7676
struct mutex lock;
7777
struct regmap *regmap;
78+
/* Ensure naturally aligned timestamp */
79+
struct {
80+
u16 channels[2];
81+
s64 ts __aligned(8);
82+
} scan;
7883
};
7984

8085
/* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */
@@ -488,7 +493,6 @@ static irqreturn_t max44000_trigger_handler(int irq, void *p)
488493
struct iio_poll_func *pf = p;
489494
struct iio_dev *indio_dev = pf->indio_dev;
490495
struct max44000_data *data = iio_priv(indio_dev);
491-
u16 buf[8]; /* 2x u16 + padding + 8 bytes timestamp */
492496
int index = 0;
493497
unsigned int regval;
494498
int ret;
@@ -498,17 +502,17 @@ static irqreturn_t max44000_trigger_handler(int irq, void *p)
498502
ret = max44000_read_alsval(data);
499503
if (ret < 0)
500504
goto out_unlock;
501-
buf[index++] = ret;
505+
data->scan.channels[index++] = ret;
502506
}
503507
if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) {
504508
ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, &regval);
505509
if (ret < 0)
506510
goto out_unlock;
507-
buf[index] = regval;
511+
data->scan.channels[index] = regval;
508512
}
509513
mutex_unlock(&data->lock);
510514

511-
iio_push_to_buffers_with_timestamp(indio_dev, buf,
515+
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
512516
iio_get_time_ns(indio_dev));
513517
iio_trigger_notify_done(indio_dev->trig);
514518
return IRQ_HANDLED;

0 commit comments

Comments
 (0)