aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2016-12-23 21:06:10 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-26 02:24:39 -0500
commitbeecb1e72cc5af0921c9daf75c404408744822cd (patch)
treecf10ca067f334e1d8bf529dc4c4ed3843e14f427
parent33038189bcabe9fecfef79adf985539b954e0c7c (diff)
qla2xxx: Fix crash due to null pointer access
commit fc1ffd6cb38a1c1af625b9833c41928039e733f5 upstream. 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 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 56d6142852a5..078d797cb492 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3489,7 +3489,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3489 sizeof(struct ct6_dsd), 0, 3489 sizeof(struct ct6_dsd), 0,
3490 SLAB_HWCACHE_ALIGN, NULL); 3490 SLAB_HWCACHE_ALIGN, NULL);
3491 if (!ctx_cachep) 3491 if (!ctx_cachep)
3492 goto fail_free_gid_list; 3492 goto fail_free_srb_mempool;
3493 } 3493 }
3494 ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ, 3494 ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ,
3495 ctx_cachep); 3495 ctx_cachep);
@@ -3642,7 +3642,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3642 ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), 3642 ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
3643 GFP_KERNEL); 3643 GFP_KERNEL);
3644 if (!ha->loop_id_map) 3644 if (!ha->loop_id_map)
3645 goto fail_async_pd; 3645 goto fail_loop_id_map;
3646 else { 3646 else {
3647 qla2x00_set_reserved_loop_ids(ha); 3647 qla2x00_set_reserved_loop_ids(ha);
3648 ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, 3648 ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
@@ -3651,6 +3651,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3651 3651
3652 return 0; 3652 return 0;
3653 3653
3654fail_loop_id_map:
3655 dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
3654fail_async_pd: 3656fail_async_pd:
3655 dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); 3657 dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
3656fail_ex_init_cb: 3658fail_ex_init_cb:
@@ -3678,6 +3680,10 @@ fail_free_ms_iocb:
3678 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); 3680 dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
3679 ha->ms_iocb = NULL; 3681 ha->ms_iocb = NULL;
3680 ha->ms_iocb_dma = 0; 3682 ha->ms_iocb_dma = 0;
3683
3684 if (ha->sns_cmd)
3685 dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
3686 ha->sns_cmd, ha->sns_cmd_dma);
3681fail_dma_pool: 3687fail_dma_pool:
3682 if (IS_QLA82XX(ha) || ql2xenabledif) { 3688 if (IS_QLA82XX(ha) || ql2xenabledif) {
3683 dma_pool_destroy(ha->fcp_cmnd_dma_pool); 3689 dma_pool_destroy(ha->fcp_cmnd_dma_pool);
@@ -3695,10 +3701,12 @@ fail_free_nvram:
3695 kfree(ha->nvram); 3701 kfree(ha->nvram);
3696 ha->nvram = NULL; 3702 ha->nvram = NULL;
3697fail_free_ctx_mempool: 3703fail_free_ctx_mempool:
3698 mempool_destroy(ha->ctx_mempool); 3704 if (ha->ctx_mempool)
3705 mempool_destroy(ha->ctx_mempool);
3699 ha->ctx_mempool = NULL; 3706 ha->ctx_mempool = NULL;
3700fail_free_srb_mempool: 3707fail_free_srb_mempool:
3701 mempool_destroy(ha->srb_mempool); 3708 if (ha->srb_mempool)
3709 mempool_destroy(ha->srb_mempool);
3702 ha->srb_mempool = NULL; 3710 ha->srb_mempool = NULL;
3703fail_free_gid_list: 3711fail_free_gid_list:
3704 dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 3712 dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),