]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: mpi3mr: Fix possible crash when setting up bsg fails
authorGuixin Liu <kanie@linux.alibaba.com>
Tue, 7 Jan 2025 02:20:32 +0000 (10:20 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 10 Jan 2025 23:07:17 +0000 (18:07 -0500)
If bsg_setup_queue() fails, the bsg_queue is assigned a non-NULL value.
Consequently, in mpi3mr_bsg_exit(), the condition "if(!mrioc->bsg_queue)"
will not be satisfied, preventing execution from entering
bsg_remove_queue(), which could lead to the following crash:

BUG: kernel NULL pointer dereference, address: 000000000000041c
Call Trace:
  <TASK>
  mpi3mr_bsg_exit+0x1f/0x50 [mpi3mr]
  mpi3mr_remove+0x6f/0x340 [mpi3mr]
  pci_device_remove+0x3f/0xb0
  device_release_driver_internal+0x19d/0x220
  unbind_store+0xa4/0xb0
  kernfs_fop_write_iter+0x11f/0x200
  vfs_write+0x1fc/0x3e0
  ksys_write+0x67/0xe0
  do_syscall_64+0x38/0x80
  entry_SYSCALL_64_after_hwframe+0x78/0xe2

Fixes: 4268fa751365 ("scsi: mpi3mr: Add bsg device support")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Link: https://lore.kernel.org/r/20250107022032.24006-1-kanie@linux.alibaba.com
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr_app.c

index 10b8e4dc64f8b0cdf66256859327bc0f60660dbc..7589f48aebc80f53949426b81bb16fc841431d0e 100644 (file)
@@ -2951,6 +2951,7 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
                .max_hw_sectors         = MPI3MR_MAX_APP_XFER_SECTORS,
                .max_segments           = MPI3MR_MAX_APP_XFER_SEGMENTS,
        };
+       struct request_queue *q;
 
        device_initialize(bsg_dev);
 
@@ -2966,14 +2967,17 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc)
                return;
        }
 
-       mrioc->bsg_queue = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim,
+       q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim,
                        mpi3mr_bsg_request, NULL, 0);
-       if (IS_ERR(mrioc->bsg_queue)) {
+       if (IS_ERR(q)) {
                ioc_err(mrioc, "%s: bsg registration failed\n",
                    dev_name(bsg_dev));
                device_del(bsg_dev);
                put_device(bsg_dev);
+               return;
        }
+
+       mrioc->bsg_queue = q;
 }
 
 /**