diff options
author | Julia Lawall <Julia.Lawall@lip6.fr> | 2013-01-07 05:00:16 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2013-01-19 18:16:40 -0500 |
commit | 17bebdcd5c7c56cde82b8ccb02c5cea69e05f6d3 (patch) | |
tree | 4f2eb74f269a44c2961dc6f74c4572031fb32ef8 /drivers/crypto/bfin_crc.c | |
parent | d20fb18be246d196225ed151c126832b2dab6506 (diff) |
crypto: bfin_crc - reposition free_irq to avoid access to invalid data
The data referenced by an interrupt handler should not be freed before the
interrupt is ended. The handler is bfin_crypto_crc_handler. It may refer
to crc->regs, which is released by the iounmap.
Furthermore, the second argument to all calls to free_irq is incorrect. It
should be the same as the last argument of request_irq, which is crc,
rather than crc->dev.
The semantic match that finds the first problem is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@fn exists@
expression list es;
expression a,b;
identifier f;
@@
if (...) {
... when any
free_irq(a,b);
... when any
f(es);
... when any
return ...;
}
@@
expression list fn.es;
expression fn.a,fn.b;
identifier fn.f;
@@
*f(es);
... when any
*free_irq(a,b);
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/bfin_crc.c')
-rw-r--r-- | drivers/crypto/bfin_crc.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/crypto/bfin_crc.c b/drivers/crypto/bfin_crc.c index 5398580b4313..06fa1e4f49d3 100644 --- a/drivers/crypto/bfin_crc.c +++ b/drivers/crypto/bfin_crc.c | |||
@@ -694,7 +694,7 @@ out_error_dma: | |||
694 | dma_free_coherent(&pdev->dev, PAGE_SIZE, crc->sg_cpu, crc->sg_dma); | 694 | dma_free_coherent(&pdev->dev, PAGE_SIZE, crc->sg_cpu, crc->sg_dma); |
695 | free_dma(crc->dma_ch); | 695 | free_dma(crc->dma_ch); |
696 | out_error_irq: | 696 | out_error_irq: |
697 | free_irq(crc->irq, crc->dev); | 697 | free_irq(crc->irq, crc); |
698 | out_error_unmap: | 698 | out_error_unmap: |
699 | iounmap((void *)crc->regs); | 699 | iounmap((void *)crc->regs); |
700 | out_error_free_mem: | 700 | out_error_free_mem: |
@@ -720,10 +720,10 @@ static int __devexit bfin_crypto_crc_remove(struct platform_device *pdev) | |||
720 | 720 | ||
721 | crypto_unregister_ahash(&algs); | 721 | crypto_unregister_ahash(&algs); |
722 | tasklet_kill(&crc->done_task); | 722 | tasklet_kill(&crc->done_task); |
723 | iounmap((void *)crc->regs); | ||
724 | free_dma(crc->dma_ch); | 723 | free_dma(crc->dma_ch); |
725 | if (crc->irq > 0) | 724 | if (crc->irq > 0) |
726 | free_irq(crc->irq, crc->dev); | 725 | free_irq(crc->irq, crc); |
726 | iounmap((void *)crc->regs); | ||
727 | kfree(crc); | 727 | kfree(crc); |
728 | 728 | ||
729 | return 0; | 729 | return 0; |