Skip to content

Commit 02ad21c

Browse files
committed
iio:magnetometer:ak8975 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 apart from previous readings. The explicit alignment of ts is not necessary in this case as by coincidence the padding will end up the same, however I consider it to make the code less fragile and have included it. Fixes: bc11ca4 ("iio:magnetometer:ak8975: triggered buffer support") Reported-by: Lars-Peter Clausen <lars@metafoo.de> Cc: Gregor Boirie <gregor.boirie@parrot.com> Cc: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: <Stable@vger.kernel.org>
1 parent 2684d50 commit 02ad21c

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

drivers/iio/magnetometer/ak8975.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ struct ak8975_data {
366366
struct iio_mount_matrix orientation;
367367
struct regulator *vdd;
368368
struct regulator *vid;
369+
370+
/* Ensure natural alignment of timestamp */
371+
struct {
372+
s16 channels[3];
373+
s64 ts __aligned(8);
374+
} scan;
369375
};
370376

371377
/* Enable attached power regulator if any. */
@@ -793,7 +799,6 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
793799
const struct i2c_client *client = data->client;
794800
const struct ak_def *def = data->def;
795801
int ret;
796-
s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
797802
__le16 fval[3];
798803

799804
mutex_lock(&data->lock);
@@ -816,12 +821,13 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
816821
mutex_unlock(&data->lock);
817822

818823
/* Clamp to valid range. */
819-
buff[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
820-
buff[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
821-
buff[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
824+
data->scan.channels[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
825+
data->scan.channels[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
826+
data->scan.channels[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
822827

823-
iio_push_to_buffers_with_timestamp(indio_dev, buff,
828+
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
824829
iio_get_time_ns(indio_dev));
830+
825831
return;
826832

827833
unlock:

0 commit comments

Comments
 (0)