* [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location
@ 2026-05-05 13:37 David Carlier
2026-05-06 6:39 ` Andy Shevchenko
0 siblings, 1 reply; 4+ messages in thread
From: David Carlier @ 2026-05-05 13:37 UTC (permalink / raw)
To: Jonathan Cameron
Cc: dlechner, nuno.sa, andy, linux-iio, linux-kernel, stable,
David Carlier
itg3200_read_all_channels() takes `__be16 *buf' as a parameter and
fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the
parameter (a pointer), `&buf' is the address of the local pointer
slot on the stack of itg3200_read_all_channels(), not the address
of the caller's scan buffer. The (char *) cast hides the type
mismatch.
i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16)
= 8 bytes into the parameter's stack slot, which is discarded when
the function returns. The caller's scan buffer in
itg3200_trigger_handler() is never written to, so
iio_push_to_buffers_with_timestamp() pushes uninitialised stack
contents to userspace via /dev/iio:deviceX every scan -- both a
functional bug (no actual gyroscope or temperature data is
delivered through the triggered buffer) and an information leak.
The non-buffered read_raw() path is unaffected: it goes through
itg3200_read_reg_s16() which uses `&out' on a local s16 value,
where that is correct.
Drop the spurious `&' so the i2c read writes into the caller's
buffer.
Fixes: 9dbf091da080 ("iio: gyro: Add itg3200")
Cc: stable@vger.kernel.org
Signed-off-by: David Carlier <devnexen@gmail.com>
---
drivers/iio/gyro/itg3200_buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c
index a624400a239c..0d3a50031d76 100644
--- a/drivers/iio/gyro/itg3200_buffer.c
+++ b/drivers/iio/gyro/itg3200_buffer.c
@@ -34,7 +34,7 @@ static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf)
.addr = i2c->addr,
.flags = i2c->flags | I2C_M_RD,
.len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
- .buf = (char *)&buf,
+ .buf = (char *)buf,
},
};
--
2.53.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location
2026-05-05 13:37 [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location David Carlier
@ 2026-05-06 6:39 ` Andy Shevchenko
2026-05-06 7:08 ` David CARLIER
0 siblings, 1 reply; 4+ messages in thread
From: Andy Shevchenko @ 2026-05-06 6:39 UTC (permalink / raw)
To: David Carlier
Cc: Jonathan Cameron, dlechner, nuno.sa, andy, linux-iio,
linux-kernel, stable
On Tue, May 05, 2026 at 02:37:48PM +0100, David Carlier wrote:
> itg3200_read_all_channels() takes `__be16 *buf' as a parameter and
> fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the
> parameter (a pointer), `&buf' is the address of the local pointer
> slot on the stack of itg3200_read_all_channels(), not the address
> of the caller's scan buffer. The (char *) cast hides the type
> mismatch.
>
> i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16)
> = 8 bytes into the parameter's stack slot, which is discarded when
> the function returns. The caller's scan buffer in
> itg3200_trigger_handler() is never written to, so
> iio_push_to_buffers_with_timestamp() pushes uninitialised stack
> contents to userspace via /dev/iio:deviceX every scan -- both a
> functional bug (no actual gyroscope or temperature data is
> delivered through the triggered buffer) and an information leak.
>
> The non-buffered read_raw() path is unaffected: it goes through
> itg3200_read_reg_s16() which uses `&out' on a local s16 value,
> where that is correct.
>
> Drop the spurious `&' so the i2c read writes into the caller's
> buffer.
Very good catch! I'm puzzled if that code was ever tested. Do you have an HW
and that's how you enter to this bug?
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location
2026-05-06 6:39 ` Andy Shevchenko
@ 2026-05-06 7:08 ` David CARLIER
2026-05-06 17:37 ` Jonathan Cameron
0 siblings, 1 reply; 4+ messages in thread
From: David CARLIER @ 2026-05-06 7:08 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, dlechner, nuno.sa, andy, linux-iio,
linux-kernel, stable
On Wed, 6 May 2026 at 07:40, Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
>
> On Tue, May 05, 2026 at 02:37:48PM +0100, David Carlier wrote:
> > itg3200_read_all_channels() takes `__be16 *buf' as a parameter and
> > fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the
> > parameter (a pointer), `&buf' is the address of the local pointer
> > slot on the stack of itg3200_read_all_channels(), not the address
> > of the caller's scan buffer. The (char *) cast hides the type
> > mismatch.
> >
> > i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16)
> > = 8 bytes into the parameter's stack slot, which is discarded when
> > the function returns. The caller's scan buffer in
> > itg3200_trigger_handler() is never written to, so
> > iio_push_to_buffers_with_timestamp() pushes uninitialised stack
> > contents to userspace via /dev/iio:deviceX every scan -- both a
> > functional bug (no actual gyroscope or temperature data is
> > delivered through the triggered buffer) and an information leak.
> >
> > The non-buffered read_raw() path is unaffected: it goes through
> > itg3200_read_reg_s16() which uses `&out' on a local s16 value,
> > where that is correct.
> >
> > Drop the spurious `&' so the i2c read writes into the caller's
> > buffer.
>
> Very good catch! I'm puzzled if that code was ever tested. Do you have an HW
> and that's how you enter to this bug?
>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
Thanks! No HW on my side -- found by inspection. I had recently looked
at a similar `(char *)&buf' / `(char *)buf' mix-up in another
driver,
so I went grepping for the same shape and itg3200 stood out. For
contrast, drivers/iio/humidity/hdc3020.c::hdc3020_read_bytes() has
the
same signature (u8 *buf parameter) and assigns `.buf = buf'
correctly.
Compile-tested only; the analysis in the changelog is what I'm
relying
on.
Cheers !
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location
2026-05-06 7:08 ` David CARLIER
@ 2026-05-06 17:37 ` Jonathan Cameron
0 siblings, 0 replies; 4+ messages in thread
From: Jonathan Cameron @ 2026-05-06 17:37 UTC (permalink / raw)
To: David CARLIER
Cc: Andy Shevchenko, dlechner, nuno.sa, andy, linux-iio, linux-kernel,
stable
On Wed, 6 May 2026 08:08:24 +0100
David CARLIER <devnexen@gmail.com> wrote:
> On Wed, 6 May 2026 at 07:40, Andy Shevchenko
> <andriy.shevchenko@intel.com> wrote:
> >
> > On Tue, May 05, 2026 at 02:37:48PM +0100, David Carlier wrote:
> > > itg3200_read_all_channels() takes `__be16 *buf' as a parameter and
> > > fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the
> > > parameter (a pointer), `&buf' is the address of the local pointer
> > > slot on the stack of itg3200_read_all_channels(), not the address
> > > of the caller's scan buffer. The (char *) cast hides the type
> > > mismatch.
> > >
> > > i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16)
> > > = 8 bytes into the parameter's stack slot, which is discarded when
> > > the function returns. The caller's scan buffer in
> > > itg3200_trigger_handler() is never written to, so
> > > iio_push_to_buffers_with_timestamp() pushes uninitialised stack
> > > contents to userspace via /dev/iio:deviceX every scan -- both a
> > > functional bug (no actual gyroscope or temperature data is
> > > delivered through the triggered buffer) and an information leak.
> > >
> > > The non-buffered read_raw() path is unaffected: it goes through
> > > itg3200_read_reg_s16() which uses `&out' on a local s16 value,
> > > where that is correct.
> > >
> > > Drop the spurious `&' so the i2c read writes into the caller's
> > > buffer.
> >
> > Very good catch! I'm puzzled if that code was ever tested. Do you have an HW
> > and that's how you enter to this bug?
> >
> > Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> >
> > --
> > With Best Regards,
> > Andy Shevchenko
> >
> >
>
> Thanks! No HW on my side -- found by inspection. I had recently looked
> at a similar `(char *)&buf' / `(char *)buf' mix-up in another
> driver,
> so I went grepping for the same shape and itg3200 stood out. For
> contrast, drivers/iio/humidity/hdc3020.c::hdc3020_read_bytes() has
> the
> same signature (u8 *buf parameter) and assigns `.buf = buf'
> correctly.
>
> Compile-tested only; the analysis in the changelog is what I'm
> relying
> on.
>
> Cheers !
I was assuming the fixes tag was wrong and this was a result of
rework, but you are correct it goes all they way back!
Huh. I guess last minute driver changes that didn't quite get
tested and clearly not a heavily used device! 13 years of
not working.
We could drop the driver, but it's possible it is in use
just not with buffered support (which is a separate CONFIG option)
Also drops don't get backported so we'd be leaving it broken and
stale. So let's fix it now and consider a drop later.
Applied to the fixes-togreg branch of iio.git
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-05-06 17:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-05 13:37 [PATCH] iio: gyro: itg3200: fix i2c read into the wrong stack location David Carlier
2026-05-06 6:39 ` Andy Shevchenko
2026-05-06 7:08 ` David CARLIER
2026-05-06 17:37 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox