In ibmvfc_purge_requests() the variables shwqs and nhwqs are declared as:

    int shwqs, nhwqs = 0;

This initialises only nhwqs to zero; shwqs is left uninitialised. Both
are assigned inside the 'if (vhost->using_channels)' block, so when
using_channels is false the block is skipped and shwqs retains its
garbage stack value. The subsequent loop

    for (i = 0; i < shwqs; i++)

then iterates an arbitrary number of times over scsi_scrqs.scrqs[], which
may be NULL on the non-channel path, resulting in out-of-bounds heap
accesses and a kernel crash during any adapter reset or shutdown that
occurs before channels are established.

Fix by initialising shwqs to 0 in the declaration so that both loop
bounds are zero when using_channels is false and neither sub-queue loop
executes.

Fixes: 4857949b58cd ("ibmvfc: fail nvme-fc fcp-io and ls requests during 
transport reset")
Signed-off-by: Tyrel Datwyler <[email protected]>
---
 drivers/scsi/ibmvscsi/ibmvfc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c 
b/drivers/scsi/ibmvscsi/ibmvfc-core.c
index e4a21ca6815d..5ba8058991ef 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
@@ -1192,7 +1192,7 @@ static void ibmvfc_purge_requests(struct ibmvfc_host 
*vhost, int error_code)
        struct ibmvfc_queue *scsi_q = vhost->scsi_scrqs.scrqs;
        struct ibmvfc_queue *nvme_q = vhost->nvme_scrqs.scrqs;
        unsigned long flags;
-       int shwqs, nhwqs = 0;
+       int shwqs = 0, nhwqs = 0;
        int i;
 
        if (vhost->using_channels) {
-- 
2.55.0


Reply via email to