Skip to content

Commit 838e00b

Browse files
committed
iio:magnetometer:ak8974: Fix alignment and data leak issues
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 an 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. This data is allocated with kzalloc so no data can leak appart from previous readings. Fixes: 7c94a8b ("iio: magn: add a driver for AK8974") Reported-by: Lars-Peter Clausen <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]> Cc: <[email protected]>
1 parent e9c6004 commit 838e00b

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

drivers/iio/magnetometer/ak8974.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ struct ak8974 {
192192
bool drdy_irq;
193193
struct completion drdy_complete;
194194
bool drdy_active_low;
195+
/* Ensure timestamp is naturally aligned */
196+
struct {
197+
__le16 channels[3];
198+
s64 ts __aligned(8);
199+
} scan;
195200
};
196201

197202
static const char ak8974_reg_avdd[] = "avdd";
@@ -657,7 +662,6 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
657662
{
658663
struct ak8974 *ak8974 = iio_priv(indio_dev);
659664
int ret;
660-
__le16 hw_values[8]; /* Three axes + 64bit padding */
661665

662666
pm_runtime_get_sync(&ak8974->i2c->dev);
663667
mutex_lock(&ak8974->lock);
@@ -667,13 +671,13 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
667671
dev_err(&ak8974->i2c->dev, "error triggering measure\n");
668672
goto out_unlock;
669673
}
670-
ret = ak8974_getresult(ak8974, hw_values);
674+
ret = ak8974_getresult(ak8974, ak8974->scan.channels);
671675
if (ret) {
672676
dev_err(&ak8974->i2c->dev, "error getting measures\n");
673677
goto out_unlock;
674678
}
675679

676-
iio_push_to_buffers_with_timestamp(indio_dev, hw_values,
680+
iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan,
677681
iio_get_time_ns(indio_dev));
678682

679683
out_unlock:

0 commit comments

Comments
 (0)