Skip to content

Commit

Permalink
iio:accel:mma8452: Fix timestamp alignment and prevent data leak.
Browse files Browse the repository at this point in the history
commit 89226a296d816727405d3fea684ef69e7d388bd8 upstream.

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 u8 array 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
ensured by use of an explicit c structure.  This data is allocated
with kzalloc so no data can leak appart from previous readings.

The additional forcing of the 8 byte alignment of the timestamp
is not strictly necessary but makes the code less fragile by
making this explicit.

Fixes: c7eeea9 ("iio: Add Freescale MMA8452Q 3-axis accelerometer driver")
Reported-by: Lars-Peter Clausen <[email protected]>
Cc: Peter Meerwald <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
Reviewed-by: Andy Shevchenko <[email protected]>
Cc: <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
jic23 authored and gregkh committed Sep 23, 2020
1 parent 69be397 commit 7bc5f67
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions drivers/iio/accel/mma8452.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ struct mma8452_data {
u8 ctrl_reg1;
u8 data_cfg;
const struct mma_chip_info *chip_info;

/* Ensure correct alignment of time stamp when present */
struct {
__be16 channels[3];
s64 ts __aligned(8);
} buffer;
};

/**
Expand Down Expand Up @@ -985,14 +991,13 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct mma8452_data *data = iio_priv(indio_dev);
u8 buffer[16]; /* 3 16-bit channels + padding + ts */
int ret;

ret = mma8452_read(data, (__be16 *)buffer);
ret = mma8452_read(data, data->buffer.channels);
if (ret < 0)
goto done;

iio_push_to_buffers_with_timestamp(indio_dev, buffer,
iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
iio_get_time_ns(indio_dev));

done:
Expand Down

0 comments on commit 7bc5f67

Please sign in to comment.