Re: [RFC PATCH] scsi: fix oops in scsi_uninit_cmd()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02/19/2019 08:27 AM, Jason Yan wrote:
If we remove the scsi disk when running io with fio, oops occured with
the following condition.

[scsi_eh_0]                              [fio]
scsi_end_request
   ->blk_update_request
     ->end_bio(io returned to userspace)
                                          close
                                            ->sd_release
                                               ->scsi_disk_put
                                                  ->scsi_disk_release
                                                      ->disk->private_data = NULL;

   ->scsi_mq_uninit_cmd
     ->scsi_uninit_cmd
       ->scsi_cmd_to_driver
     ->drv is NULL, Oops

There is a small window between blk_update_request() and
scsi_mq_uninit_cmd() that scsi disk may have been released. This will
cause a oops like below:

To fix this, get a refcount of scsi_disk in sd_init_command() to ensure
it will not be released before sd_uninit_command().

Signed-off-by: Jason Yan <yanaijie@xxxxxxxxxx>
---
  drivers/scsi/sd.c | 46 +++++++++++++++++++++++++++++++++++-----------
  1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5464d467e23e..6bdb8fbb570f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1249,42 +1249,64 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
  static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
  {
  	struct request *rq = cmd->request;
+	struct scsi_disk *sdkp = NULL;

This pre-init with NULL kinda prevents static compile warnings on uninitialized use?

+	blk_status_t ret;

  	switch (req_op(rq)) {

  	}
+
+	if (!ret) {
+		sdkp = scsi_disk(rq->rq_disk);
+		get_device(&sdkp->dev);
+	}
+
+	return ret;
  }

  static void sd_uninit_command(struct scsi_cmnd *SCpnt)
  {
  	struct request *rq = SCpnt->request;
  	u8 *cmnd;
+	struct scsi_disk *sdkp = NULL;

dito


  	if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
  		mempool_free(rq->special_vec.bv_page, sd_page_pool);
@@ -1295,6 +1317,8 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
  		SCpnt->cmd_len = 0;
  		mempool_free(cmnd, sd_cdb_pool);
  	}
+	sdkp = scsi_disk(rq->rq_disk);
+	put_device(&sdkp->dev);
  }

  /**



--
Mit freundlichen Gruessen / Kind regards
Steffen Maier

Linux on IBM Z Development

https://www.ibm.com/privacy/us/en/
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Matthias Hartmann
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux