lkml.org 
[lkml]   [2020]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 054/215] iio:health:afe4403 Fix timestamp alignment and prevent data leak.
    Date
    From: Jonathan Cameron <Jonathan.Cameron@huawei.com>

    commit 3f9c6d38797e9903937b007a341dad0c251765d6 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 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 appart from previous readings.

    Fixes: eec96d1e2d31 ("iio: health: Add driver for the TI AFE4403 heart monitor")
    Reported-by: Lars-Peter Clausen <lars@metafoo.de>
    Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
    Acked-by: Andrew F. Davis <afd@ti.com>
    Cc: <Stable@vger.kernel.org>
    Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/iio/health/afe4403.c | 13 ++++++++-----
    1 file changed, 8 insertions(+), 5 deletions(-)

    --- a/drivers/iio/health/afe4403.c
    +++ b/drivers/iio/health/afe4403.c
    @@ -63,6 +63,7 @@ static const struct reg_field afe4403_re
    * @regulator: Pointer to the regulator for the IC
    * @trig: IIO trigger for this device
    * @irq: ADC_RDY line interrupt number
    + * @buffer: Used to construct data layout to push into IIO buffer.
    */
    struct afe4403_data {
    struct device *dev;
    @@ -72,6 +73,8 @@ struct afe4403_data {
    struct regulator *regulator;
    struct iio_trigger *trig;
    int irq;
    + /* Ensure suitable alignment for timestamp */
    + s32 buffer[8] __aligned(8);
    };

    enum afe4403_chan_id {
    @@ -309,7 +312,6 @@ static irqreturn_t afe4403_trigger_handl
    struct iio_dev *indio_dev = pf->indio_dev;
    struct afe4403_data *afe = iio_priv(indio_dev);
    int ret, bit, i = 0;
    - s32 buffer[8];
    u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
    u8 rx[3];

    @@ -326,9 +328,9 @@ static irqreturn_t afe4403_trigger_handl
    if (ret)
    goto err;

    - buffer[i++] = (rx[0] << 16) |
    - (rx[1] << 8) |
    - (rx[2]);
    + afe->buffer[i++] = (rx[0] << 16) |
    + (rx[1] << 8) |
    + (rx[2]);
    }

    /* Disable reading from the device */
    @@ -337,7 +339,8 @@ static irqreturn_t afe4403_trigger_handl
    if (ret)
    goto err;

    - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
    + iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
    + pf->timestamp);
    err:
    iio_trigger_notify_done(indio_dev->trig);


    \
     
     \ /
      Last update: 2020-07-20 18:34    [W:4.767 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site