]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Sep 2020 12:18:24 +0000 (14:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Sep 2020 12:18:24 +0000 (14:18 +0200)
added patches:
drivers-iio-magnetometer-fix-sparse-endianness-warnings-cast-to-restricted-__be16.patch
iio-accel-kxsd9-fix-alignment-of-local-buffer.patch
iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch
iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch
iio-adc-ti-adc081c-fix-alignment-and-data-leak-issues.patch
iio-light-max44000-fix-timestamp-alignment-and-prevent-data-leak.patch
iio-magnetometer-ak8975-fix-alignment-and-data-leak-issues.patch
staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch
usb-core-add-helpers-to-retrieve-endpoints.patch

queue-4.9/drivers-iio-magnetometer-fix-sparse-endianness-warnings-cast-to-restricted-__be16.patch [new file with mode: 0644]
queue-4.9/iio-accel-kxsd9-fix-alignment-of-local-buffer.patch [new file with mode: 0644]
queue-4.9/iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch [new file with mode: 0644]
queue-4.9/iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch [new file with mode: 0644]
queue-4.9/iio-adc-ti-adc081c-fix-alignment-and-data-leak-issues.patch [new file with mode: 0644]
queue-4.9/iio-light-max44000-fix-timestamp-alignment-and-prevent-data-leak.patch [new file with mode: 0644]
queue-4.9/iio-magnetometer-ak8975-fix-alignment-and-data-leak-issues.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch [new file with mode: 0644]
queue-4.9/usb-core-add-helpers-to-retrieve-endpoints.patch [new file with mode: 0644]

diff --git a/queue-4.9/drivers-iio-magnetometer-fix-sparse-endianness-warnings-cast-to-restricted-__be16.patch b/queue-4.9/drivers-iio-magnetometer-fix-sparse-endianness-warnings-cast-to-restricted-__be16.patch
new file mode 100644 (file)
index 0000000..31f2973
--- /dev/null
@@ -0,0 +1,83 @@
+From 69c72ec9c80bbd206c6fac73874d73e69cc623b4 Mon Sep 17 00:00:00 2001
+From: Sandhya Bankar <bankarsandhya512@gmail.com>
+Date: Sun, 25 Sep 2016 18:33:17 +0530
+Subject: drivers: iio: magnetometer: Fix sparse endianness warnings cast to restricted __be16
+
+From: Sandhya Bankar <bankarsandhya512@gmail.com>
+
+commit 69c72ec9c80bbd206c6fac73874d73e69cc623b4 upstream.
+
+Fix the following sparse endianness warnings:
+
+drivers/iio/magnetometer/ak8975.c:716:16: warning: cast to restricted __le16
+drivers/iio/magnetometer/ak8975.c:837:19: warning: cast to restricted __le16
+drivers/iio/magnetometer/ak8975.c:838:19: warning: cast to restricted __le16
+drivers/iio/magnetometer/ak8975.c:839:19: warning: cast to restricted __le16
+
+Signed-off-by: Sandhya Bankar <bankarsandhya512@gmail.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/magnetometer/ak8975.c |   16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -690,6 +690,7 @@ static int ak8975_read_axis(struct iio_d
+       struct ak8975_data *data = iio_priv(indio_dev);
+       const struct i2c_client *client = data->client;
+       const struct ak_def *def = data->def;
++      __le16 rval;
+       u16 buff;
+       int ret;
+@@ -703,7 +704,7 @@ static int ak8975_read_axis(struct iio_d
+       ret = i2c_smbus_read_i2c_block_data_or_emulated(
+                       client, def->data_regs[index],
+-                      sizeof(buff), (u8*)&buff);
++                      sizeof(rval), (u8*)&rval);
+       if (ret < 0)
+               goto exit;
+@@ -713,7 +714,7 @@ static int ak8975_read_axis(struct iio_d
+       pm_runtime_put_autosuspend(&data->client->dev);
+       /* Swap bytes and convert to valid range. */
+-      buff = le16_to_cpu(buff);
++      buff = le16_to_cpu(rval);
+       *val = clamp_t(s16, buff, -def->range, def->range);
+       return IIO_VAL_INT;
+@@ -813,6 +814,7 @@ static void ak8975_fill_buffer(struct ii
+       const struct ak_def *def = data->def;
+       int ret;
+       s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
++      __le16 fval[3];
+       mutex_lock(&data->lock);
+@@ -826,17 +828,17 @@ static void ak8975_fill_buffer(struct ii
+        */
+       ret = i2c_smbus_read_i2c_block_data_or_emulated(client,
+                                                       def->data_regs[0],
+-                                                      3 * sizeof(buff[0]),
+-                                                      (u8 *)buff);
++                                                      3 * sizeof(fval[0]),
++                                                      (u8 *)fval);
+       if (ret < 0)
+               goto unlock;
+       mutex_unlock(&data->lock);
+       /* Clamp to valid range. */
+-      buff[0] = clamp_t(s16, le16_to_cpu(buff[0]), -def->range, def->range);
+-      buff[1] = clamp_t(s16, le16_to_cpu(buff[1]), -def->range, def->range);
+-      buff[2] = clamp_t(s16, le16_to_cpu(buff[2]), -def->range, def->range);
++      buff[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
++      buff[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
++      buff[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
+       iio_push_to_buffers_with_timestamp(indio_dev, buff,
+                                          iio_get_time_ns(indio_dev));
diff --git a/queue-4.9/iio-accel-kxsd9-fix-alignment-of-local-buffer.patch b/queue-4.9/iio-accel-kxsd9-fix-alignment-of-local-buffer.patch
new file mode 100644 (file)
index 0000000..df1755a
--- /dev/null
@@ -0,0 +1,64 @@
+From 95ad67577de4ea08eb8e441394e698aa4addcc0b Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:37 +0100
+Subject: iio: accel: kxsd9: Fix alignment of local buffer.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 95ad67577de4ea08eb8e441394e698aa4addcc0b upstream.
+
+iio_push_to_buffers_with_timestamp assumes 8 byte alignment which
+is not guaranteed by an array of smaller elements.
+
+Note that whilst in this particular case the alignment forcing
+of the ts element is not strictly necessary it acts as good
+documentation.  Doing this where not necessary should cut
+down on the number of cut and paste introduced errors elsewhere.
+
+Fixes: 0427a106a98a ("iio: accel: kxsd9: Add triggered buffer handling")
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/accel/kxsd9.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/iio/accel/kxsd9.c
++++ b/drivers/iio/accel/kxsd9.c
+@@ -212,14 +212,20 @@ static irqreturn_t kxsd9_trigger_handler
+       const struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct kxsd9_state *st = iio_priv(indio_dev);
++      /*
++       * Ensure correct positioning and alignment of timestamp.
++       * No need to zero initialize as all elements written.
++       */
++      struct {
++              __be16 chan[4];
++              s64 ts __aligned(8);
++      } hw_values;
+       int ret;
+-      /* 4 * 16bit values AND timestamp */
+-      __be16 hw_values[8];
+       ret = regmap_bulk_read(st->map,
+                              KXSD9_REG_X,
+-                             &hw_values,
+-                             8);
++                             hw_values.chan,
++                             sizeof(hw_values.chan));
+       if (ret) {
+               dev_err(st->dev,
+                       "error reading data\n");
+@@ -227,7 +233,7 @@ static irqreturn_t kxsd9_trigger_handler
+       }
+       iio_push_to_buffers_with_timestamp(indio_dev,
+-                                         hw_values,
++                                         &hw_values,
+                                          iio_get_time_ns(indio_dev));
+       iio_trigger_notify_done(indio_dev->trig);
diff --git a/queue-4.9/iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch b/queue-4.9/iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch
new file mode 100644 (file)
index 0000000..1875bca
--- /dev/null
@@ -0,0 +1,74 @@
+From 7e5ac1f2206eda414f90c698fe1820dee873394d Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:40 +0100
+Subject: iio:accel:mma7455: Fix timestamp alignment and prevent data leak.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 7e5ac1f2206eda414f90c698fe1820dee873394d 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 force alignment of ts is not strictly necessary in this particularly
+case but does make the code less fragile.
+
+Fixes: a84ef0d181d9 ("iio: accel: add Freescale MMA7455L/MMA7456L 3-axis accelerometer driver")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: <Stable@vger.kernel.org>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/accel/mma7455_core.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/accel/mma7455_core.c
++++ b/drivers/iio/accel/mma7455_core.c
+@@ -55,6 +55,14 @@
+ struct mma7455_data {
+       struct regmap *regmap;
++      /*
++       * Used to reorganize data.  Will ensure correct alignment of
++       * the timestamp if present
++       */
++      struct {
++              __le16 channels[3];
++              s64 ts __aligned(8);
++      } scan;
+ };
+ static int mma7455_drdy(struct mma7455_data *mma7455)
+@@ -85,19 +93,19 @@ static irqreturn_t mma7455_trigger_handl
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct mma7455_data *mma7455 = iio_priv(indio_dev);
+-      u8 buf[16]; /* 3 x 16-bit channels + padding + ts */
+       int ret;
+       ret = mma7455_drdy(mma7455);
+       if (ret)
+               goto done;
+-      ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf,
+-                             sizeof(__le16) * 3);
++      ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL,
++                             mma7455->scan.channels,
++                             sizeof(mma7455->scan.channels));
+       if (ret)
+               goto done;
+-      iio_push_to_buffers_with_timestamp(indio_dev, buf,
++      iio_push_to_buffers_with_timestamp(indio_dev, &mma7455->scan,
+                                          iio_get_time_ns(indio_dev));
+ done:
diff --git a/queue-4.9/iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch b/queue-4.9/iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch
new file mode 100644 (file)
index 0000000..c9116a1
--- /dev/null
@@ -0,0 +1,67 @@
+From 89226a296d816727405d3fea684ef69e7d388bd8 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:38 +0100
+Subject: iio:accel:mma8452: Fix timestamp alignment and prevent data leak.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+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: c7eeea93ac60 ("iio: Add Freescale MMA8452Q 3-axis accelerometer driver")
+Reported-by: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/accel/mma8452.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/accel/mma8452.c
++++ b/drivers/iio/accel/mma8452.c
+@@ -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;
+ };
+ /**
+@@ -985,14 +991,13 @@ static irqreturn_t mma8452_trigger_handl
+       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:
diff --git a/queue-4.9/iio-adc-ti-adc081c-fix-alignment-and-data-leak-issues.patch b/queue-4.9/iio-adc-ti-adc081c-fix-alignment-and-data-leak-issues.patch
new file mode 100644 (file)
index 0000000..7b6b428
--- /dev/null
@@ -0,0 +1,66 @@
+From 54f82df2ba86e2a8e9cbf4036d192366e3905c89 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:56 +0100
+Subject: iio:adc:ti-adc081c Fix alignment and data leak issues
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 54f82df2ba86e2a8e9cbf4036d192366e3905c89 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 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().
+
+This data is allocated with kzalloc so no data can leak apart
+from previous readings.
+
+The eplicit alignment of ts is necessary to ensure correct padding
+on x86_32 where s64 is only aligned to 4 bytes.
+
+Fixes: 08e05d1fce5c ("ti-adc081c: 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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/adc/ti-adc081c.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/adc/ti-adc081c.c
++++ b/drivers/iio/adc/ti-adc081c.c
+@@ -36,6 +36,12 @@ struct adc081c {
+       /* 8, 10 or 12 */
+       int bits;
++
++      /* Ensure natural alignment of buffer elements */
++      struct {
++              u16 channel;
++              s64 ts __aligned(8);
++      } scan;
+ };
+ #define REG_CONV_RES 0x00
+@@ -132,14 +138,13 @@ static irqreturn_t adc081c_trigger_handl
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct adc081c *data = iio_priv(indio_dev);
+-      u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
+       int ret;
+       ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES);
+       if (ret < 0)
+               goto out;
+-      buf[0] = ret;
+-      iio_push_to_buffers_with_timestamp(indio_dev, buf,
++      data->scan.channel = ret;
++      iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+                                          iio_get_time_ns(indio_dev));
+ out:
+       iio_trigger_notify_done(indio_dev->trig);
diff --git a/queue-4.9/iio-light-max44000-fix-timestamp-alignment-and-prevent-data-leak.patch b/queue-4.9/iio-light-max44000-fix-timestamp-alignment-and-prevent-data-leak.patch
new file mode 100644 (file)
index 0000000..d5280f3
--- /dev/null
@@ -0,0 +1,77 @@
+From 523628852a5f5f34a15252b2634d0498d3cfb347 Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:45 +0100
+Subject: iio:light:max44000 Fix timestamp alignment and prevent data leak.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 523628852a5f5f34a15252b2634d0498d3cfb347 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 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: 06ad7ea10e2b ("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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/light/max44000.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/light/max44000.c
++++ b/drivers/iio/light/max44000.c
+@@ -78,6 +78,11 @@
+ struct max44000_data {
+       struct mutex lock;
+       struct regmap *regmap;
++      /* Ensure naturally aligned timestamp */
++      struct {
++              u16 channels[2];
++              s64 ts __aligned(8);
++      } scan;
+ };
+ /* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */
+@@ -491,7 +496,6 @@ static irqreturn_t max44000_trigger_hand
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct max44000_data *data = iio_priv(indio_dev);
+-      u16 buf[8]; /* 2x u16 + padding + 8 bytes timestamp */
+       int index = 0;
+       unsigned int regval;
+       int ret;
+@@ -501,17 +505,17 @@ static irqreturn_t max44000_trigger_hand
+               ret = max44000_read_alsval(data);
+               if (ret < 0)
+                       goto out_unlock;
+-              buf[index++] = ret;
++              data->scan.channels[index++] = ret;
+       }
+       if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) {
+               ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, &regval);
+               if (ret < 0)
+                       goto out_unlock;
+-              buf[index] = regval;
++              data->scan.channels[index] = regval;
+       }
+       mutex_unlock(&data->lock);
+-      iio_push_to_buffers_with_timestamp(indio_dev, buf,
++      iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+                                          iio_get_time_ns(indio_dev));
+       iio_trigger_notify_done(indio_dev->trig);
+       return IRQ_HANDLED;
diff --git a/queue-4.9/iio-magnetometer-ak8975-fix-alignment-and-data-leak-issues.patch b/queue-4.9/iio-magnetometer-ak8975-fix-alignment-and-data-leak-issues.patch
new file mode 100644 (file)
index 0000000..b88650b
--- /dev/null
@@ -0,0 +1,78 @@
+From 02ad21cefbac4d89ac443866f25b90449527737b Mon Sep 17 00:00:00 2001
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Date: Wed, 22 Jul 2020 16:50:49 +0100
+Subject: iio:magnetometer:ak8975 Fix alignment and data leak issues.
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+commit 02ad21cefbac4d89ac443866f25b90449527737b 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 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: bc11ca4a0b84 ("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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/magnetometer/ak8975.c |   16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/iio/magnetometer/ak8975.c
++++ b/drivers/iio/magnetometer/ak8975.c
+@@ -381,6 +381,12 @@ struct ak8975_data {
+       struct iio_mount_matrix orientation;
+       struct regulator        *vdd;
+       struct regulator        *vid;
++
++      /* Ensure natural alignment of timestamp */
++      struct {
++              s16 channels[3];
++              s64 ts __aligned(8);
++      } scan;
+ };
+ /* Enable attached power regulator if any. */
+@@ -813,7 +819,6 @@ static void ak8975_fill_buffer(struct ii
+       const struct i2c_client *client = data->client;
+       const struct ak_def *def = data->def;
+       int ret;
+-      s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */
+       __le16 fval[3];
+       mutex_lock(&data->lock);
+@@ -836,12 +841,13 @@ static void ak8975_fill_buffer(struct ii
+       mutex_unlock(&data->lock);
+       /* Clamp to valid range. */
+-      buff[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
+-      buff[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
+-      buff[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
++      data->scan.channels[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range);
++      data->scan.channels[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
++      data->scan.channels[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
+-      iio_push_to_buffers_with_timestamp(indio_dev, buff,
++      iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
+                                          iio_get_time_ns(indio_dev));
++
+       return;
+ unlock:
index e7720bcb3979fa6848db9a2021145f07762ce6db..7547020d6cf73ae0cb35699e987eeff614962fb6 100644 (file)
@@ -18,3 +18,12 @@ iio-adc-ti-ads1015-fix-conversion-when-config_pm-is-not-set.patch
 iio-light-ltr501-fix-timestamp-alignment-issue.patch
 iio-accel-bmc150-accel-fix-timestamp-alignment-and-prevent-data-leak.patch
 iio-adc-ina2xx-fix-timestamp-alignment-issue.patch
+iio-adc-ti-adc081c-fix-alignment-and-data-leak-issues.patch
+drivers-iio-magnetometer-fix-sparse-endianness-warnings-cast-to-restricted-__be16.patch
+iio-magnetometer-ak8975-fix-alignment-and-data-leak-issues.patch
+iio-light-max44000-fix-timestamp-alignment-and-prevent-data-leak.patch
+iio-accel-kxsd9-fix-alignment-of-local-buffer.patch
+iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch
+iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch
+usb-core-add-helpers-to-retrieve-endpoints.patch
+staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch
diff --git a/queue-4.9/staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch b/queue-4.9/staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch
new file mode 100644 (file)
index 0000000..764088a
--- /dev/null
@@ -0,0 +1,84 @@
+From fea22e159d51c766ba70473f473a0ec914cc7e92 Mon Sep 17 00:00:00 2001
+From: Rustam Kovhaev <rkovhaev@gmail.com>
+Date: Tue, 4 Aug 2020 07:56:14 -0700
+Subject: staging: wlan-ng: fix out of bounds read in prism2sta_probe_usb()
+
+From: Rustam Kovhaev <rkovhaev@gmail.com>
+
+commit fea22e159d51c766ba70473f473a0ec914cc7e92 upstream.
+
+let's use usb_find_common_endpoints() to discover endpoints, it does all
+necessary checks for type and xfer direction
+
+remove memset() in hfa384x_create(), because we now assign endpoints in
+prism2sta_probe_usb() and because create_wlan() uses kzalloc() to
+allocate hfa384x struct before calling hfa384x_create()
+
+Fixes: faaff9765664 ("staging: wlan-ng: properly check endpoint types")
+Reported-and-tested-by: syzbot+22794221ab96b0bab53a@syzkaller.appspotmail.com
+Link: https://syzkaller.appspot.com/bug?extid=22794221ab96b0bab53a
+Signed-off-by: Rustam Kovhaev <rkovhaev@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200804145614.104320-1-rkovhaev@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/wlan-ng/hfa384x_usb.c |    5 -----
+ drivers/staging/wlan-ng/prism2usb.c   |   19 ++++++-------------
+ 2 files changed, 6 insertions(+), 18 deletions(-)
+
+--- a/drivers/staging/wlan-ng/hfa384x_usb.c
++++ b/drivers/staging/wlan-ng/hfa384x_usb.c
+@@ -523,13 +523,8 @@ static void hfa384x_usb_defer(struct wor
+ ----------------------------------------------------------------*/
+ void hfa384x_create(struct hfa384x *hw, struct usb_device *usb)
+ {
+-      memset(hw, 0, sizeof(struct hfa384x));
+       hw->usb = usb;
+-      /* set up the endpoints */
+-      hw->endp_in = usb_rcvbulkpipe(usb, 1);
+-      hw->endp_out = usb_sndbulkpipe(usb, 2);
+-
+       /* Set up the waitq */
+       init_waitqueue_head(&hw->cmdq);
+--- a/drivers/staging/wlan-ng/prism2usb.c
++++ b/drivers/staging/wlan-ng/prism2usb.c
+@@ -60,23 +60,14 @@ static int prism2sta_probe_usb(struct us
+                              const struct usb_device_id *id)
+ {
+       struct usb_device *dev;
+-      const struct usb_endpoint_descriptor *epd;
+-      const struct usb_host_interface *iface_desc = interface->cur_altsetting;
++      struct usb_endpoint_descriptor *bulk_in, *bulk_out;
++      struct usb_host_interface *iface_desc = interface->cur_altsetting;
+       struct wlandevice *wlandev = NULL;
+       struct hfa384x *hw = NULL;
+       int result = 0;
+-      if (iface_desc->desc.bNumEndpoints != 2) {
+-              result = -ENODEV;
+-              goto failed;
+-      }
+-
+-      result = -EINVAL;
+-      epd = &iface_desc->endpoint[1].desc;
+-      if (!usb_endpoint_is_bulk_in(epd))
+-              goto failed;
+-      epd = &iface_desc->endpoint[2].desc;
+-      if (!usb_endpoint_is_bulk_out(epd))
++      result = usb_find_common_endpoints(iface_desc, &bulk_in, &bulk_out, NULL, NULL);
++      if (result)
+               goto failed;
+       dev = interface_to_usbdev(interface);
+@@ -95,6 +86,8 @@ static int prism2sta_probe_usb(struct us
+       }
+       /* Initialize the hw data */
++      hw->endp_in = usb_rcvbulkpipe(dev, bulk_in->bEndpointAddress);
++      hw->endp_out = usb_sndbulkpipe(dev, bulk_out->bEndpointAddress);
+       hfa384x_create(hw, dev);
+       hw->wlandev = wlandev;
diff --git a/queue-4.9/usb-core-add-helpers-to-retrieve-endpoints.patch b/queue-4.9/usb-core-add-helpers-to-retrieve-endpoints.patch
new file mode 100644 (file)
index 0000000..a3cad6c
--- /dev/null
@@ -0,0 +1,166 @@
+From 66a359390e7e34f9a4c489467234b107b3d76169 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Mar 2017 11:35:30 +0100
+Subject: USB: core: add helpers to retrieve endpoints
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 66a359390e7e34f9a4c489467234b107b3d76169 upstream.
+
+Many USB drivers iterate over the available endpoints to find required
+endpoints of a specific type and direction. Typically the endpoints are
+required for proper function and a missing endpoint should abort probe.
+
+To facilitate code reuse, add a helper to retrieve common endpoints
+(bulk or interrupt, in or out) and four wrappers to find a single
+endpoint.
+
+Note that the helpers are marked as __must_check to serve as a reminder
+to always verify that all expected endpoints are indeed present. This
+also means that any optional endpoints, typically need to be looked up
+through separate calls.
+
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/usb.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/usb.h    |   35 ++++++++++++++++++++
+ 2 files changed, 118 insertions(+)
+
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -73,6 +73,89 @@ MODULE_PARM_DESC(autosuspend, "default a
+ /**
++ * usb_find_common_endpoints() -- look up common endpoint descriptors
++ * @alt:      alternate setting to search
++ * @bulk_in:  pointer to descriptor pointer, or NULL
++ * @bulk_out: pointer to descriptor pointer, or NULL
++ * @int_in:   pointer to descriptor pointer, or NULL
++ * @int_out:  pointer to descriptor pointer, or NULL
++ *
++ * Search the alternate setting's endpoint descriptors for the first bulk-in,
++ * bulk-out, interrupt-in and interrupt-out endpoints and return them in the
++ * provided pointers (unless they are NULL).
++ *
++ * If a requested endpoint is not found, the corresponding pointer is set to
++ * NULL.
++ *
++ * Return: Zero if all requested descriptors were found, or -ENXIO otherwise.
++ */
++int usb_find_common_endpoints(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **bulk_in,
++              struct usb_endpoint_descriptor **bulk_out,
++              struct usb_endpoint_descriptor **int_in,
++              struct usb_endpoint_descriptor **int_out)
++{
++      struct usb_endpoint_descriptor *epd;
++      int i;
++
++      if (bulk_in)
++              *bulk_in = NULL;
++      if (bulk_out)
++              *bulk_out = NULL;
++      if (int_in)
++              *int_in = NULL;
++      if (int_out)
++              *int_out = NULL;
++
++      for (i = 0; i < alt->desc.bNumEndpoints; ++i) {
++              epd = &alt->endpoint[i].desc;
++
++              switch (usb_endpoint_type(epd)) {
++              case USB_ENDPOINT_XFER_BULK:
++                      if (usb_endpoint_dir_in(epd)) {
++                              if (bulk_in && !*bulk_in) {
++                                      *bulk_in = epd;
++                                      break;
++                              }
++                      } else {
++                              if (bulk_out && !*bulk_out) {
++                                      *bulk_out = epd;
++                                      break;
++                              }
++                      }
++
++                      continue;
++              case USB_ENDPOINT_XFER_INT:
++                      if (usb_endpoint_dir_in(epd)) {
++                              if (int_in && !*int_in) {
++                                      *int_in = epd;
++                                      break;
++                              }
++                      } else {
++                              if (int_out && !*int_out) {
++                                      *int_out = epd;
++                                      break;
++                              }
++                      }
++
++                      continue;
++              default:
++                      continue;
++              }
++
++              if ((!bulk_in || *bulk_in) &&
++                              (!bulk_out || *bulk_out) &&
++                              (!int_in || *int_in) &&
++                              (!int_out || *int_out)) {
++                      return 0;
++              }
++      }
++
++      return -ENXIO;
++}
++EXPORT_SYMBOL_GPL(usb_find_common_endpoints);
++
++/**
+  * usb_find_alt_setting() - Given a configuration, find the alternate setting
+  * for the given interface.
+  * @config: the configuration to search (not necessarily the current config).
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -99,6 +99,41 @@ enum usb_interface_condition {
+       USB_INTERFACE_UNBINDING,
+ };
++int __must_check
++usb_find_common_endpoints(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **bulk_in,
++              struct usb_endpoint_descriptor **bulk_out,
++              struct usb_endpoint_descriptor **int_in,
++              struct usb_endpoint_descriptor **int_out);
++
++static inline int __must_check
++usb_find_bulk_in_endpoint(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **bulk_in)
++{
++      return usb_find_common_endpoints(alt, bulk_in, NULL, NULL, NULL);
++}
++
++static inline int __must_check
++usb_find_bulk_out_endpoint(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **bulk_out)
++{
++      return usb_find_common_endpoints(alt, NULL, bulk_out, NULL, NULL);
++}
++
++static inline int __must_check
++usb_find_int_in_endpoint(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **int_in)
++{
++      return usb_find_common_endpoints(alt, NULL, NULL, int_in, NULL);
++}
++
++static inline int __must_check
++usb_find_int_out_endpoint(struct usb_host_interface *alt,
++              struct usb_endpoint_descriptor **int_out)
++{
++      return usb_find_common_endpoints(alt, NULL, NULL, NULL, int_out);
++}
++
+ /**
+  * struct usb_interface - what usb device drivers talk to
+  * @altsetting: array of interface structures, one for each alternate