diff options
author | Maurizio Lombardi <mlombard@redhat.com> | 2014-04-01 07:58:21 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-05-19 13:29:57 -0400 |
commit | 91d9f809da44b42de95a0b9058deea7268bde3c2 (patch) | |
tree | 357e90d1a9f23f6244d45fb0c5bafd47982aa653 /drivers/scsi/bnx2fc | |
parent | b044d1498cbfef5e11c9c390288f4b841c9b328c (diff) |
bnx2fc: fix memory leak and potential NULL pointer dereference.
If bnx2fc_allocate_hash_table() for some reasons fails, it is possible that the
hash_tbl_segments or the hash_tbl_pbl pointers are NULL.
In this case bnx2fc_free_hash_table() will panic the system.
this patch also fixes a memory leak, the hash_tbl_segments pointer was never
freed.
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Acked-by: Eddie Wai <eddie.wai@broadcom.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/bnx2fc')
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_hwi.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 261af2a41d24..f83bae48e6b7 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c | |||
@@ -1968,21 +1968,27 @@ static void bnx2fc_free_hash_table(struct bnx2fc_hba *hba) | |||
1968 | int segment_count; | 1968 | int segment_count; |
1969 | u32 *pbl; | 1969 | u32 *pbl; |
1970 | 1970 | ||
1971 | segment_count = hba->hash_tbl_segment_count; | 1971 | if (hba->hash_tbl_segments) { |
1972 | 1972 | ||
1973 | pbl = hba->hash_tbl_pbl; | 1973 | pbl = hba->hash_tbl_pbl; |
1974 | for (i = 0; i < segment_count; ++i) { | 1974 | if (pbl) { |
1975 | dma_addr_t dma_address; | 1975 | segment_count = hba->hash_tbl_segment_count; |
1976 | 1976 | for (i = 0; i < segment_count; ++i) { | |
1977 | dma_address = le32_to_cpu(*pbl); | 1977 | dma_addr_t dma_address; |
1978 | ++pbl; | 1978 | |
1979 | dma_address += ((u64)le32_to_cpu(*pbl)) << 32; | 1979 | dma_address = le32_to_cpu(*pbl); |
1980 | ++pbl; | 1980 | ++pbl; |
1981 | dma_free_coherent(&hba->pcidev->dev, | 1981 | dma_address += ((u64)le32_to_cpu(*pbl)) << 32; |
1982 | BNX2FC_HASH_TBL_CHUNK_SIZE, | 1982 | ++pbl; |
1983 | hba->hash_tbl_segments[i], | 1983 | dma_free_coherent(&hba->pcidev->dev, |
1984 | dma_address); | 1984 | BNX2FC_HASH_TBL_CHUNK_SIZE, |
1985 | hba->hash_tbl_segments[i], | ||
1986 | dma_address); | ||
1987 | } | ||
1988 | } | ||
1985 | 1989 | ||
1990 | kfree(hba->hash_tbl_segments); | ||
1991 | hba->hash_tbl_segments = NULL; | ||
1986 | } | 1992 | } |
1987 | 1993 | ||
1988 | if (hba->hash_tbl_pbl) { | 1994 | if (hba->hash_tbl_pbl) { |