Re: [PATCH] iio: triggered-buffer: prevent possible freeing of wrong buffer

From: Jonathan Cameron
Date: Sun Nov 26 2023 - 12:19:21 EST


On Thu, 2 Nov 2023 09:53:13 -0500
David Lechner <dlechner@xxxxxxxxxxxx> wrote:

> On Thu, Nov 2, 2023 at 3:59 AM Nuno Sá <noname.nuno@xxxxxxxxx> wrote:
> >
> > On Tue, 2023-10-31 at 16:05 -0500, David Lechner wrote:
> > > Commit ee708e6baacd ("iio: buffer: introduce support for attaching more
> > > IIO buffers") introduced support for multiple buffers per indio_dev but
> > > left indio_dev->buffer for a few legacy use cases.
> > >
> > > In the case of the triggered buffer, iio_triggered_buffer_cleanup()
> > > still assumes that indio_dev->buffer points to the buffer allocated by
> > > iio_triggered_buffer_setup_ext(). However, since
> > > iio_triggered_buffer_setup_ext() now calls iio_device_attach_buffer()
> > > to attach the buffer, indio_dev->buffer will only point to the buffer
> > > allocated by iio_device_attach_buffer() if it the first buffer attached.
> > >
> > > This adds a check to make sure that no other buffer has been attached
> > > yet to ensure that indio_dev->buffer will be assigned when
> > > iio_device_attach_buffer() is called.
> > >
> > > Fixes: ee708e6baacd ("iio: buffer: introduce support for attaching more IIO
> > > buffers")
> > > Signed-off-by: David Lechner <dlechner@xxxxxxxxxxxx>
> > > ---
> > > drivers/iio/buffer/industrialio-triggered-buffer.c | 10 ++++++++++
> > > 1 file changed, 10 insertions(+)
> > >
> > > diff --git a/drivers/iio/buffer/industrialio-triggered-buffer.c
> > > b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > > index c7671b1f5ead..c06515987e7a 100644
> > > --- a/drivers/iio/buffer/industrialio-triggered-buffer.c
> > > +++ b/drivers/iio/buffer/industrialio-triggered-buffer.c
> > > @@ -46,6 +46,16 @@ int iio_triggered_buffer_setup_ext(struct iio_dev
> > > *indio_dev,
> > > struct iio_buffer *buffer;
> > > int ret;
> > >
> > > + /*
> > > + * iio_triggered_buffer_cleanup() assumes that the buffer allocated
> > > here
> > > + * is assigned to indio_dev->buffer but this is only the case if this
> > > + * function is the first caller to iio_device_attach_buffer(). If
> > > + * indio_dev->buffer is already set then we can't proceed otherwise
> > > the
> > > + * cleanup function will try to free a buffer that was not allocated
> > > here.
> > > + */
> > > + if (indio_dev->buffer)
> > > + return -EADDRINUSE;
> > > +
> >
> > Hmmm, good catch! But I think this is just workarounding the real problem
>
> Yes, I could have done a better job explaining my reason for this fix.
> It seemed like the simplest fix that could be easily backported to
> stable kernels. And then we can look at removing the legacy field
> completely in the future.
>
> > because like this, you can only have a triggered buffer by device. This should
> > be fine as we don't really have any multi buffer user so far but ideally it
> > should be possible.

So far multibufferred devices have always been for cases where triggers don't make
sense (devices with multiple hardware fifos that run out of step or where a single
fifo is filled unevenly from different sensors, or big complex dma based devices
where the trigger concept doesn't map at all.)

I agree that it sort of make sense to make the trigger per buffer, but in practice
I'm not sure on what sort of device will need it. Mind you, I guess you hit this
in practice which rather implies something does!

> >
> > Long term we might want to think about moving 'pollfunc' to be a per buffer
> > thing. Not sure how much trouble that would be given that a trigger is also per
> > device and I don't know if it would make sense to have a trigger per buffer?!
> > Ideally, given the multi buffer concept, I would say it makes sense but it might
> > be difficult to accomplish. So better to think about it only if there's a real
> > usecase for it.
> >
> > On thing that I guess it could be done is to change the triggered API so it
> > returns a buffer and so iio_triggered_buffer_cleanup() would also get a pointer
> > to the buffer it allocated (similar to what DMA buffer's are doing). But that's
> > indeed also bigger change... Bahh, I'm likely over complicating things for now.
>
> This sounds very much like the work I am doing on SPI Engine offload
> support - having a trigger associated with a buffer. So maybe
> something will come out of that. ¯\_(ツ)_/¯

Ah. I guess if the trigger is being used to route things out of sight of software that
might be a case where we do need multiple triggers per device...

Doesn't sound 'too' hard to make work and we'll end up with similar case to buffers
where
iio_deviceX/current_trigger maps to the one for buffer0 so no ABI breakage, just new
toys to play with.
>
> > Fell free to:
> >
> > Acked-by: Nuno Sa <nuno.sa@xxxxxxxxxx>
> >
> >
Applied with a note that we may revisit adding multiple triggers support in future
but that is unlikely to be suitable for a backport as it's a new feature.

Applied to the fixes-togreg branch of iio.git and marked for stable.

Thanks,

Jonathan