aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2021-11-07 13:59:42 +0100
committerHannes Reinecke <hare@suse.de>2021-11-07 13:59:42 +0100
commit24f76588c2ef9b23dea2ead5dca53992e15d083b (patch)
tree7c508da676041ef5ddfd8184487643ca9026af7e
parented0e30387b1f9b2bfd439f14d15e83506e322b78 (diff)
downloadscsi-devel-24f76588c2ef9b23dea2ead5dca53992e15d083b.tar.gz
scsi: check for NULL queuedata
For the admin queue the 'queuedata' pointer is NULL, so we need to check for an empty queuedata pointer to avoid a null pointer dereference if a command destined for the admin queue is misdirected to a normal I/O queue. Signed-off-by: Hannes Reinecke <hare@suse.de>
-rw-r--r--drivers/scsi/scsi_lib.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 62102e6f3a5dc..500da673466c9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -452,6 +452,8 @@ static void scsi_run_queue(struct request_queue *q)
{
struct scsi_device *sdev = q->queuedata;
+ if (!sdev)
+ return;
if (scsi_target(sdev)->single_lun)
scsi_single_lun_run(sdev);
if (!list_empty(&sdev->host->starved_list))
@@ -1240,6 +1242,9 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
{
int token;
+ if (!sdev)
+ return -1;
+
token = sbitmap_get(&sdev->budget_map);
if (atomic_read(&sdev->device_blocked)) {
if (token < 0)
@@ -1389,6 +1394,8 @@ static bool scsi_mq_lld_busy(struct request_queue *q)
struct scsi_device *sdev = q->queuedata;
struct Scsi_Host *shost;
+ if (!sdev)
+ return false;
if (blk_queue_dying(q))
return false;
@@ -1535,9 +1542,11 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
{
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
struct scsi_device *sdev = req->q->queuedata;
- struct Scsi_Host *shost = sdev->host;
+ struct Scsi_Host *shost;
struct scatterlist *sg;
+ if (!sdev)
+ return BLK_STS_OK;
scsi_init_command(sdev, cmd);
cmd->prot_op = SCSI_PROT_NORMAL;
@@ -1546,6 +1555,7 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
else
cmd->sc_data_direction = DMA_NONE;
+ shost = sdev->host;
sg = (void *)cmd + sizeof(struct scsi_cmnd) + shost->hostt->cmd_size;
cmd->sdb.table.sgl = sg;
@@ -1607,6 +1617,9 @@ static int scsi_mq_get_budget(struct request_queue *q)
struct scsi_device *sdev = q->queuedata;
int token = scsi_dev_queue_ready(q, sdev);
+ if (!sdev)
+ return -1;
+ token = scsi_device_queue_ready(q, sdev);
if (token >= 0)
return token;
@@ -1653,11 +1666,15 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
struct request *req = bd->rq;
struct request_queue *q = req->q;
struct scsi_device *sdev = q->queuedata;
- struct Scsi_Host *shost = sdev->host;
+ struct Scsi_Host *shost;
struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
blk_status_t ret;
int reason;
+ if (!sdev)
+ return BLK_STS_IOERR;
+
+ shost = sdev->host;
WARN_ON_ONCE(cmd->budget_token < 0);
/*