Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0858d74e authored by Giridhar Malavali's avatar Giridhar Malavali Committed by Greg Kroah-Hartman
Browse files

scsi: qla2xxx: Fix for double free of SRB structure



commit bcc71cc3cde1468958a3ea859276d8d1a1a68265 upstream.

This patch fixes issue during switch command query where driver was freeing
SRB resources multiple times

Following stack trace will be seen
[  853.436234] BUG: unable to handle kernel NULL pointer dereference at
0000000000000001
[  853.436348] IP: [<ffffffff811df514>] kmem_cache_alloc+0x74/0x1e0
[  853.436476] PGD 0
[  853.436601] Oops: 0000 [#1] SMP

[  853.454700]  [<ffffffff81099f6a>] ? mod_timer+0x14a/0x220
[  853.455543]  [<ffffffff81185465>] mempool_alloc_slab+0x15/0x20
[  853.456395]  [<ffffffff811855a9>] mempool_alloc+0x69/0x170
[  853.457257]  [<ffffffff81098af2>] ? internal_add_timer+0x32/0x70
[  853.458136]  [<ffffffffc0092d2b>] qla2xxx_queuecommand+0x29b/0x3f0 [qla2xxx]
[  853.459024]  [<ffffffff8146535a>] scsi_dispatch_cmd+0xaa/0x230
[  853.459923]  [<ffffffff8146e11f>] scsi_request_fn+0x4df/0x680
[  853.460829]  [<ffffffff81029557>] ? __switch_to+0xd7/0x510
[  853.461747]  [<ffffffff812f7113>] __blk_run_queue+0x33/0x40
[  853.462670]  [<ffffffff812f7735>] blk_delay_work+0x25/0x40
[  853.463603]  [<ffffffff810a882a>] process_one_work+0x17a/0x440
[  853.464546]  [<ffffffff810a94f6>] worker_thread+0x126/0x3c0
[  853.465501]  [<ffffffff810a93d0>] ? manage_workers.isra.24+0x2a0/0x2a0
[  853.466447]  [<ffffffff810b099f>] kthread+0xcf/0xe0
[  853.467379]  [<ffffffff810b08d0>] ? insert_kthread_work+0x40/0x40
[  853.470172] Code: db e2 7e 49 8b 50 08 4d 8b 20 49 8b 40 10 4d 85 e4 0f 84 20
01 00 00 48 85 c0 0f 84 17 01 00 00 49 63 46 20 48 8d 4a 01 4d 8b 06 <49> 8b 1c
04 4c 89 e0 65 49 0f c7 08 0f 94 c0 84 c0 74 ba 49 63
[  853.472072] RIP  [<ffffffff811df514>] kmem_cache_alloc+0x74/0x1e0
[  853.472971]  RSP <ffff88103726fc50>

Fixes: 726b8548 ("qla2xxx: Add framework for async fabric discovery")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@cavium.com>
Reviewed-by: default avatarEwan D. Milne <emilne@redhat.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 966faef4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3261,6 +3261,9 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
	    "Async done-%s res %x, WWPN %8phC \n",
	    sp->name, res, fcport->port_name);

	if (res == QLA_FUNCTION_TIMEOUT)
		return;

	if (res == (DID_ERROR << 16)) {
		/* entry status error */
		goto done;
+13 −2
Original line number Diff line number Diff line
@@ -52,12 +52,14 @@ qla2x00_sp_timeout(struct timer_list *t)
	struct srb_iocb *iocb;
	struct req_que *req;
	unsigned long flags;
	struct qla_hw_data *ha = sp->vha->hw;

	spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
	WARN_ON(irqs_disabled());
	spin_lock_irqsave(&ha->hardware_lock, flags);
	req = sp->qpair->req;
	req->outstanding_cmds[sp->handle] = NULL;
	iocb = &sp->u.iocb_cmd;
	spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
	iocb->timeout(sp);
}

@@ -972,6 +974,15 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)

	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);

	if (res == QLA_FUNCTION_TIMEOUT)
		return;

	if (res == QLA_FUNCTION_TIMEOUT) {
		dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
			sp->u.iocb_cmd.u.mbx.in_dma);
		return;
	}

	memset(&ea, 0, sizeof(ea));
	ea.event = FCME_GPDB_DONE;
	ea.fcport = fcport;