> -----Original Message----- > From: Kees Cook <keescook@xxxxxxxxxxxx> > Sent: Thursday, December 16, 2021 1:23 AM > To: Lars-Peter Clausen <lars@xxxxxxxxxx> > Cc: Kees Cook <keescook@xxxxxxxxxxxx>; Hennerich, Michael > <Michael.Hennerich@xxxxxxxxxx>; Tanislav, Cosmin > <Cosmin.Tanislav@xxxxxxxxxx>; Jonathan Cameron <jic23@xxxxxxxxxx>; > Linus Walleij <linus.walleij@xxxxxxxxxx>; linux-kernel@xxxxxxxxxxxxxxx; linux- > iio@xxxxxxxxxxxxxxx; linux-hardening@xxxxxxxxxxxxxxx > Subject: [PATCH] iio: addac: Do not reference negative array offsets > > [External] > > Instead of aiming rx_buf at an invalid array-boundary-crossing location, > just skip the first assignment. Seen when building with -Warray-bounds: > > drivers/iio/addac/ad74413r.c: In function 'ad74413r_update_scan_mode': > drivers/iio/addac/ad74413r.c:843:22: warning: array subscript -4 is below > array bounds of 'u8[16]' { aka 'unsigned char[16]'} [-Warray-bounds] > 843 | u8 *rx_buf = &st->adc_samples_buf.rx_buf[-1 * > AD74413R_FRAME_SIZE]; > | > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > drivers/iio/addac/ad74413r.c:84:20: note: while referencing 'rx_buf' > 84 | u8 rx_buf[AD74413R_FRAME_SIZE * > AD74413R_CHANNEL_MAX]; > | ^~~~~~ > > Fixes: fea251b6a5db ("iio: addac: add AD74413R driver") > Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> > --- > drivers/iio/addac/ad74413r.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c > index cbd9aa9b399a..b0a6d8ee5133 100644 > --- a/drivers/iio/addac/ad74413r.c > +++ b/drivers/iio/addac/ad74413r.c > @@ -840,7 +840,7 @@ static int ad74413r_update_scan_mode(struct iio_dev > *indio_dev, > { > struct ad74413r_state *st = iio_priv(indio_dev); > struct spi_transfer *xfer = st->adc_samples_xfer; > - u8 *rx_buf = &st->adc_samples_buf.rx_buf[-1 * > AD74413R_FRAME_SIZE]; > + u8 *rx_buf = st->adc_samples_buf.rx_buf; > u8 *tx_buf = st->adc_samples_tx_buf; > unsigned int channel; > int ret; > @@ -877,9 +877,8 @@ static int ad74413r_update_scan_mode(struct iio_dev > *indio_dev, > if (ret) > goto out; > > - st->adc_active_channels++; > > - if (xfer == st->adc_samples_xfer) > + if (xfer == st->adc_samples_xfer || st->adc_active_channels > == 0) You can probably keep only one of the checks. Both xfer and adc_active_channels will be incremented after your changes anyway. > xfer->rx_buf = NULL; > else > xfer->rx_buf = rx_buf; > @@ -896,7 +895,10 @@ static int ad74413r_update_scan_mode(struct > iio_dev *indio_dev, > > xfer++; > tx_buf += AD74413R_FRAME_SIZE; > - rx_buf += AD74413R_FRAME_SIZE; > + if (st->adc_active_channels) > + rx_buf += AD74413R_FRAME_SIZE; > + > + st->adc_active_channels++; > } > > xfer->rx_buf = rx_buf; > -- > 2.30.2