Skip to content

Commit 5c49056

Browse files
committed
iio:humidity:hts221 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. Explicit alignment of ts needed to ensure consistent padding on all architectures (particularly x86_32 with it's 4 byte alignment of s64) Fixes: e4a70e3 ("iio: humidity: add support to hts221 rh/temp combo device") Reported-by: Lars-Peter Clausen <[email protected]> Acked-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]> Cc: <[email protected]>
1 parent ea5e7a7 commit 5c49056

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

drivers/iio/humidity/hts221.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414

1515
#include <linux/iio/iio.h>
1616

17-
#define HTS221_DATA_SIZE 2
18-
1917
enum hts221_sensor_type {
2018
HTS221_SENSOR_H,
2119
HTS221_SENSOR_T,
@@ -39,6 +37,11 @@ struct hts221_hw {
3937

4038
bool enabled;
4139
u8 odr;
40+
/* Ensure natural alignment of timestamp */
41+
struct {
42+
__le16 channels[2];
43+
s64 ts __aligned(8);
44+
} scan;
4245
};
4346

4447
extern const struct dev_pm_ops hts221_pm_ops;

drivers/iio/humidity/hts221_buffer.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ static const struct iio_buffer_setup_ops hts221_buffer_ops = {
160160

161161
static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
162162
{
163-
u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
164163
struct iio_poll_func *pf = p;
165164
struct iio_dev *iio_dev = pf->indio_dev;
166165
struct hts221_hw *hw = iio_priv(iio_dev);
@@ -170,18 +169,20 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
170169
/* humidity data */
171170
ch = &iio_dev->channels[HTS221_SENSOR_H];
172171
err = regmap_bulk_read(hw->regmap, ch->address,
173-
buffer, HTS221_DATA_SIZE);
172+
&hw->scan.channels[0],
173+
sizeof(hw->scan.channels[0]));
174174
if (err < 0)
175175
goto out;
176176

177177
/* temperature data */
178178
ch = &iio_dev->channels[HTS221_SENSOR_T];
179179
err = regmap_bulk_read(hw->regmap, ch->address,
180-
buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE);
180+
&hw->scan.channels[1],
181+
sizeof(hw->scan.channels[1]));
181182
if (err < 0)
182183
goto out;
183184

184-
iio_push_to_buffers_with_timestamp(iio_dev, buffer,
185+
iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
185186
iio_get_time_ns(iio_dev));
186187

187188
out:

0 commit comments

Comments
 (0)