aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2016-12-23 21:06:10 -0500
committerBart Van Assche <bart.vanassche@sandisk.com>2017-01-17 14:26:56 -0500
commitfc1ffd6cb38a1c1af625b9833c41928039e733f5 (patch)
tree047f9cad155c1e737155bcab9df52aced894b524
parent8d3c9c230818aa3c27edb4fd126494479d35d3d5 (diff)
qla2xxx: Fix crash due to null pointer access
During code inspection, while investigating following stack trace seen on one of the test setup, we found out there was possibility of memory leak becuase driver was not unwinding the stack properly. This issue has not been reproduced in a test environment or on a customer setup. Here's stack trace that was seen. [1469877.797315] Call Trace: [1469877.799940] [<ffffffffa03ab6e9>] qla2x00_mem_alloc+0xb09/0x10c0 [qla2xxx] [1469877.806980] [<ffffffffa03ac50a>] qla2x00_probe_one+0x86a/0x1b50 [qla2xxx] [1469877.814013] [<ffffffff813b6d01>] ? __pm_runtime_resume+0x51/0xa0 [1469877.820265] [<ffffffff8157c1f5>] ? _raw_spin_lock_irqsave+0x25/0x90 [1469877.826776] [<ffffffff8157cd2d>] ? _raw_spin_unlock_irqrestore+0x6d/0x80 [1469877.833720] [<ffffffff810741d1>] ? preempt_count_sub+0xb1/0x100 [1469877.839885] [<ffffffff8157cd0c>] ? _raw_spin_unlock_irqrestore+0x4c/0x80 [1469877.846830] [<ffffffff81319b9c>] local_pci_probe+0x4c/0xb0 [1469877.852562] [<ffffffff810741d1>] ? preempt_count_sub+0xb1/0x100 [1469877.858727] [<ffffffff81319c89>] pci_call_probe+0x89/0xb0 Cc: <stable@vger.kernel.org> Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Reviewed-by: Christoph Hellwig <hch@lst.de> [ bvanassche: Fixed spelling in patch description ] Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 8521cfe302e9..074dcca6ca5a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3662,7 +3662,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3662 sizeof(struct ct6_dsd), 0, 3662 sizeof(struct ct6_dsd), 0,
3663 SLAB_HWCACHE_ALIGN, NULL); 3663 SLAB_HWCACHE_ALIGN, NULL);
3664 if (!ctx_cachep) 3664 if (!ctx_cachep)
3665 goto fail_free_gid_list; 3665 goto fail_free_srb_mempool;
3666 } 3666 }
3667 ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ, 3667 ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ,
3668 ctx_cachep); 3668 ctx_cachep);
@@ -3815,7 +3815,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3815 ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), 3815 ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
3816 GFP_KERNEL); 3816 GFP_KERNEL);
3817 if (!ha->loop_id_map) 3817 if (!ha->loop_id_map)
3818 goto fail_async_pd; 3818 goto fail_loop_id_map;
3819 else { 3819 else {
3820 qla2x00_set_reserved_loop_ids(ha); 3820 qla2x00_set_reserved_loop_ids(ha);
3821 ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, 3821 ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
@@ -3824,6 +3824,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3824 3824
3825 return 0; 3825 return 0;
3826 3826
3827fail_loop_id_map:
3828 dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
3827fail_async_pd: 3829fail_async_pd:
3828 dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); 3830 dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
3829fail_ex_init_cb: 3831fail_ex_init_cb:
@@ -3851,6 +3853,10 @@ fail_free_ms_iocb:
3851 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); 3853 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
3852 ha->ms_iocb = NULL; 3854 ha->ms_iocb = NULL;
3853 ha->ms_iocb_dma = 0; 3855 ha->ms_iocb_dma = 0;
3856
3857 if (ha->sns_cmd)
3858 dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
3859 ha->sns_cmd, ha->sns_cmd_dma);
3854fail_dma_pool: 3860fail_dma_pool:
3855 if (IS_QLA82XX(ha) || ql2xenabledif) { 3861 if (IS_QLA82XX(ha) || ql2xenabledif) {
3856 dma_pool_destroy(ha->fcp_cmnd_dma_pool); 3862 dma_pool_destroy(ha->fcp_cmnd_dma_pool);
@@ -3868,10 +3874,12 @@ fail_free_nvram:
3868 kfree(ha->nvram); 3874 kfree(ha->nvram);
3869 ha->nvram = NULL; 3875 ha->nvram = NULL;
3870fail_free_ctx_mempool: 3876fail_free_ctx_mempool:
3871 mempool_destroy(ha->ctx_mempool); 3877 if (ha->ctx_mempool)
3878 mempool_destroy(ha->ctx_mempool);
3872 ha->ctx_mempool = NULL; 3879 ha->ctx_mempool = NULL;
3873fail_free_srb_mempool: 3880fail_free_srb_mempool:
3874 mempool_destroy(ha->srb_mempool); 3881 if (ha->srb_mempool)
3882 mempool_destroy(ha->srb_mempool);
3875 ha->srb_mempool = NULL; 3883 ha->srb_mempool = NULL;
3876fail_free_gid_list: 3884fail_free_gid_list:
3877 dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 3885 dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),