Message ID | 20190310185826.25916-1-TheSven73@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] iio: adc: xilinx: fix potential use-after-free on remove | expand |
On Sun, 10 Mar 2019 14:58:24 -0400 Sven Van Asbroeck <thesven73@gmail.com> wrote: > When cancel_delayed_work() returns, the delayed work may still > be running. This means that the core could potentially free > the private structure (struct xadc) while the delayed work > is still using it. This is a potential use-after-free. > > Fix by calling cancel_delayed_work_sync(), which waits for > any residual work to finish before returning. > > Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com> This appears 'obviously correct' to me so I'll apply it to the fixes togreg branch of iio.git and mark it for stable. However I won't be sending a pull request for that branch until at least next weekend, so if anyone more familiar with the hardware has a chance to take a look that would be great. Applied to the fixes-togreg branch of iio.git. Thanks, Jonathan > --- > drivers/iio/adc/xilinx-xadc-core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c > index 3f6be5ac049a..1960694e8007 100644 > --- a/drivers/iio/adc/xilinx-xadc-core.c > +++ b/drivers/iio/adc/xilinx-xadc-core.c > @@ -1320,7 +1320,7 @@ static int xadc_remove(struct platform_device *pdev) > } > free_irq(xadc->irq, indio_dev); > clk_disable_unprepare(xadc->clk); > - cancel_delayed_work(&xadc->zynq_unmask_work); > + cancel_delayed_work_sync(&xadc->zynq_unmask_work); > kfree(xadc->data); > kfree(indio_dev->channels); >
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 3f6be5ac049a..1960694e8007 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -1320,7 +1320,7 @@ static int xadc_remove(struct platform_device *pdev) } free_irq(xadc->irq, indio_dev); clk_disable_unprepare(xadc->clk); - cancel_delayed_work(&xadc->zynq_unmask_work); + cancel_delayed_work_sync(&xadc->zynq_unmask_work); kfree(xadc->data); kfree(indio_dev->channels);
When cancel_delayed_work() returns, the delayed work may still be running. This means that the core could potentially free the private structure (struct xadc) while the delayed work is still using it. This is a potential use-after-free. Fix by calling cancel_delayed_work_sync(), which waits for any residual work to finish before returning. Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com> --- drivers/iio/adc/xilinx-xadc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)