Clang tripped over a FORTIFY warning in this code, and while it seems it may be a false positive in Clang due to loop unwinding, the code in question seems to make a lot of assumptions. Comments added, and the Clang warning[1] has been worked around by growing the array size. Also there was an uninitialized 4th byte in the __be32 array that was being sent through to iio_push_to_buffers(). Link: https://github.com/ClangBuiltLinux/linux/issues/2000 [1] Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> --- Cc: Jonathan Cameron <jic23@xxxxxxxxxx> Cc: Lars-Peter Clausen <lars@xxxxxxxxxx> Cc: "Uwe Kleine-König" <u.kleine-koenig@xxxxxxxxxxxxxx> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Cc: "Nuno Sá" <nuno.sa@xxxxxxxxxx> Cc: linux-iio@xxxxxxxxxxxxxxx --- drivers/iio/pressure/dlhl60d.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index 28c8269ba65d..9bbecd0bfe88 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -250,20 +250,27 @@ static irqreturn_t dlh_trigger_handler(int irq, void *private) struct dlh_state *st = iio_priv(indio_dev); int ret; unsigned int chn, i = 0; - __be32 tmp_buf[2]; + /* This was only an array pair of 4 bytes. */ + __be32 tmp_buf[4] = { }; ret = dlh_start_capture_and_read(st); if (ret) goto out; + /* Nothing was checking masklength vs ARRAY_SIZE(tmp_buf)? */ + if (WARN_ON_ONCE(indio_dev->masklength > ARRAY_SIZE(tmp_buf))) + goto out; + for_each_set_bit(chn, indio_dev->active_scan_mask, indio_dev->masklength) { - memcpy(tmp_buf + i, + /* This is copying 3 bytes. What about the 4th? */ + memcpy(&tmp_buf[i], &st->rx_buf[1] + chn * DLH_NUM_DATA_BYTES, DLH_NUM_DATA_BYTES); i++; } + /* How do we know the iio buffer_list has only 2 items? */ iio_push_to_buffers(indio_dev, tmp_buf); out: -- 2.34.1