On Tue, 2012-05-15 at 02:36 +0100, Ben Hutchings wrote: > fintek-cir, ite-cir and nuvoton-cir may try to free an I/O region > and/or IRQ handler that was never allocated after a failure in their > respective probe functions. Add and use separate labels on the > failure path so they will do the right cleanup after each possible > point of failure. > > Compile-tested only. > > Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx> And this should probably go to stable as well, if you agree it's a valid fix. Ben. > --- > drivers/media/rc/fintek-cir.c | 13 ++++++------- > drivers/media/rc/ite-cir.c | 14 ++++++-------- > drivers/media/rc/nuvoton-cir.c | 26 ++++++++++++-------------- > 3 files changed, 24 insertions(+), 29 deletions(-) > > diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c > index 4a3a238..6aabf7a 100644 > --- a/drivers/media/rc/fintek-cir.c > +++ b/drivers/media/rc/fintek-cir.c > @@ -556,11 +556,11 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id > > if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED, > FINTEK_DRIVER_NAME, (void *)fintek)) > - goto failure; > + goto failure2; > > ret = rc_register_device(rdev); > if (ret) > - goto failure; > + goto failure3; > > device_init_wakeup(&pdev->dev, true); > fintek->rdev = rdev; > @@ -570,12 +570,11 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id > > return 0; > > +failure3: > + free_irq(fintek->cir_irq, fintek); > +failure2: > + release_region(fintek->cir_addr, fintek->cir_port_len); > failure: > - if (fintek->cir_irq) > - free_irq(fintek->cir_irq, fintek); > - if (fintek->cir_addr) > - release_region(fintek->cir_addr, fintek->cir_port_len); > - > rc_free_device(rdev); > kfree(fintek); > > diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c > index 0e49c99..36fe5a3 100644 > --- a/drivers/media/rc/ite-cir.c > +++ b/drivers/media/rc/ite-cir.c > @@ -1598,24 +1598,22 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id > > if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED, > ITE_DRIVER_NAME, (void *)itdev)) > - goto failure; > + goto failure2; > > ret = rc_register_device(rdev); > if (ret) > - goto failure; > + goto failure3; > > itdev->rdev = rdev; > ite_pr(KERN_NOTICE, "driver has been successfully loaded\n"); > > return 0; > > +failure3: > + free_irq(itdev->cir_irq, itdev); > +failure2: > + release_region(itdev->cir_addr, itdev->params.io_region_size); > failure: > - if (itdev->cir_irq) > - free_irq(itdev->cir_irq, itdev); > - > - if (itdev->cir_addr) > - release_region(itdev->cir_addr, itdev->params.io_region_size); > - > rc_free_device(rdev); > kfree(itdev); > > diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c > index 8b2c071..dc8a7dd 100644 > --- a/drivers/media/rc/nuvoton-cir.c > +++ b/drivers/media/rc/nuvoton-cir.c > @@ -1075,19 +1075,19 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) > > if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED, > NVT_DRIVER_NAME, (void *)nvt)) > - goto failure; > + goto failure2; > > if (!request_region(nvt->cir_wake_addr, > CIR_IOREG_LENGTH, NVT_DRIVER_NAME)) > - goto failure; > + goto failure3; > > if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED, > NVT_DRIVER_NAME, (void *)nvt)) > - goto failure; > + goto failure4; > > ret = rc_register_device(rdev); > if (ret) > - goto failure; > + goto failure5; > > device_init_wakeup(&pdev->dev, true); > nvt->rdev = rdev; > @@ -1099,17 +1099,15 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) > > return 0; > > +failure5: > + free_irq(nvt->cir_wake_irq, nvt); > +failure4: > + release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); > +failure3: > + free_irq(nvt->cir_irq, nvt); > +failure2: > + release_region(nvt->cir_addr, CIR_IOREG_LENGTH); > failure: > - if (nvt->cir_irq) > - free_irq(nvt->cir_irq, nvt); > - if (nvt->cir_addr) > - release_region(nvt->cir_addr, CIR_IOREG_LENGTH); > - > - if (nvt->cir_wake_irq) > - free_irq(nvt->cir_wake_irq, nvt); > - if (nvt->cir_wake_addr) > - release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH); > - > rc_free_device(rdev); > kfree(nvt); > -- Ben Hutchings The two most common things in the universe are hydrogen and stupidity.
Attachment:
signature.asc
Description: This is a digitally signed message part