]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: qla2xxx: Fix memory leak for allocating abort IOCB
authorQuinn Tran <quinn.tran@cavium.com>
Thu, 26 Jul 2018 23:34:44 +0000 (16:34 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 31 Jul 2018 02:04:39 +0000 (22:04 -0400)
In the case of IOCB QFull, Initiator code can leave behind a stale pointer
to an SRB structure on the outstanding command array.

Fixes: 82de802ad46e ("scsi: qla2xxx: Preparation for Target MQ.")
Cc: stable@vger.kernel.org #v4.16+
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_iocb.c

index a91cca52b5d5be5a262270ae6b0cbefe5a72a8bf..dd93a22fe84368fc827441983bcb64a0807be3ce 100644 (file)
@@ -2130,34 +2130,11 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
        req_cnt = 1;
        handle = 0;
 
-       if (!sp)
-               goto skip_cmd_array;
-
-       /* Check for room in outstanding command list. */
-       handle = req->current_outstanding_cmd;
-       for (index = 1; index < req->num_outstanding_cmds; index++) {
-               handle++;
-               if (handle == req->num_outstanding_cmds)
-                       handle = 1;
-               if (!req->outstanding_cmds[handle])
-                       break;
-       }
-       if (index == req->num_outstanding_cmds) {
-               ql_log(ql_log_warn, vha, 0x700b,
-                   "No room on outstanding cmd array.\n");
-               goto queuing_error;
-       }
-
-       /* Prep command array. */
-       req->current_outstanding_cmd = handle;
-       req->outstanding_cmds[handle] = sp;
-       sp->handle = handle;
-
-       /* Adjust entry-counts as needed. */
-       if (sp->type != SRB_SCSI_CMD)
+       if (sp && (sp->type != SRB_SCSI_CMD)) {
+               /* Adjust entry-counts as needed. */
                req_cnt = sp->iocbs;
+       }
 
-skip_cmd_array:
        /* Check for room on request queue. */
        if (req->cnt < req_cnt + 2) {
                if (qpair->use_shadow_reg)
@@ -2183,6 +2160,28 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
        if (req->cnt < req_cnt + 2)
                goto queuing_error;
 
+       if (sp) {
+               /* Check for room in outstanding command list. */
+               handle = req->current_outstanding_cmd;
+               for (index = 1; index < req->num_outstanding_cmds; index++) {
+                       handle++;
+                       if (handle == req->num_outstanding_cmds)
+                               handle = 1;
+                       if (!req->outstanding_cmds[handle])
+                               break;
+               }
+               if (index == req->num_outstanding_cmds) {
+                       ql_log(ql_log_warn, vha, 0x700b,
+                           "No room on outstanding cmd array.\n");
+                       goto queuing_error;
+               }
+
+               /* Prep command array. */
+               req->current_outstanding_cmd = handle;
+               req->outstanding_cmds[handle] = sp;
+               sp->handle = handle;
+       }
+
        /* Prep packet */
        req->cnt -= req_cnt;
        pkt = req->ring_ptr;
@@ -2195,6 +2194,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
                pkt->handle = handle;
        }
 
+       return pkt;
+
 queuing_error:
        qpair->tgt_counters.num_alloc_iocb_failed++;
        return pkt;