iio: proximity: as3935: fix use-after-free on device remove
authorSven Van Asbroeck <thesven73@gmail.com>
Fri, 8 Mar 2019 17:59:35 +0000 (12:59 -0500)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Thu, 4 Apr 2019 19:19:56 +0000 (20:19 +0100)
commit11362b7a43bac15607e26d501d6095235b38567b
tree13096dd10908a81ba30f117756d2ec474e0ecbd2
parent71a7766b36f32ece32346985e9bed63e23847914
iio: proximity: as3935: fix use-after-free on device remove

This driver's probe() uses a mix of devm_ and non-devm_ functions. This
means that the remove order will not be the exact opposite of the probe
order.

Remove order:
1. remove() executes:
iio_device_unregister
iio_triggered_buffer_cleanup
iio_trigger_unregister
(A)
2. core frees devm resources in reverse order:
free_irq
iio_trigger_free
iio_device_free

In (A) the trigger has been unregistered, but the irq handler is still
registered and active, so the trigger may still be touched via
interrupt -> as3935_event_work. This is a potential use-after-unregister.

Given that the delayed work is never canceled explicitly, it may run even
after iio_device_free. This is a potential use-after-free.

Solution: convert all probe functions to their devm_ equivalents.
Add a devm callback, called by the core on remove right after irq_free,
which explicitly cancels the delayed work. This will guarantee that all
resources are freed in the correct order.

As an added bonus, some boilerplate code can be removed.

Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/proximity/as3935.c